I'm creating a new database with the model-first approach and I want to add a column to a table of the type System.Drawing.Color
but I don't have this option in the properties list.
Is there a way to use more data types than the ones available?
I'm creating a new database with the model-first approach and I want to add a column to a table of the type System.Drawing.Color
but I don't have this option in the properties list.
Is there a way to use more data types than the ones available?
Another option here, is to use adapt the answer from Entity Framework 6 Code First - Custom Type Mapping
public class MyLittlePony {
public string Name { get; set; }
public Int32 Argb {
get {
return Color.ToArgb();
}
set {
Color = Color.FromArgb(value);
}
}
[NotMapped]
public Color Color { get; set; }
}
The NotMapped
attribute makes the entity framework not try to map the Color property to a column in the database.
One option here is to have an int
version of the ARGB colours:
public class ColorData
{
public int Id { get; set; }
public int Argb { get; set; }
public System.Drawing.Color Color
{
get { return new System.Drawing.Color.FromArgb(this.Argb); }
set
{
if(value!=null)
this.Argb = value.ToArgb();
else
this.Argb = 0;
}
}
}
In your mapping, ignore the Color
property specifically by using the fluent bindings:
protected void override OnModelCreating(ModelBuilder builder)
{
var colorTable = builder.Entity<ColorData>();
colorTable.HasKey(x => x.Id).HasColumnName("COLOR_ID");
colorTable.Property(x => x.Argb).HasColumnName("COLOR_ARGB");
colorTable.Ignore(x=>x.Color);
colorTable.ToTable("COLOR_DATA");
}
From here you now can store the data from any Color's static methods:
ColorData data = new ColorData();
data.Color = Color.Black;
data.Color = Color.FromName("Black");
data.Color = Color.FromArgb( 0xFF000000 );
data.Color = Color.FromArgb( 255, 0, 0, 0 );
One alternative chosen in the comments is to serialize as XML.
The code above uses an integer, as this uses native, efficient data types to SQL Server and is easily maintainable.
The XML version would take up much more space, is less maintainable and will now add complexity to searching for a specific colour. An expanded System.Drawing.Color
type would look like this:
<Color>
<A>123</A>
<R>45</R>
<G>67</G>
<B>89</B>
<ScA>0.482352942</ScA>
<ScR>0.0262412224</ScR>
<ScG>0.0561284944</ScG>
<ScB>0.09989873</ScB>
</Color>
Which is easier to search for the color blue?
For the int
type, this would be:
SELECT COUNT(1) FROM Customer cust
INNER JOIN Color col
ON cust.FavouriteColorId = color.Id
WHERE col.Argb = 0xFF0000FF
For the XML type:
SELECT COUNT(1) FROM Customer cust
INNER JOIN Color col
ON cust.FavouriteColorId = color.Id
WHERE col.ArgbXml.value('/Color/A') = N'255'
AND col.ArgbXml.value('/Color/R') = N'0'
AND col.ArgbXml.value('/Color/G') = N'0'
AND col.ArgbXml.value('/Color/B') = N'255'
Color
back to name? –
Blowzy Colort.FromsString(myString)
and Color.ToString()
someting like this –
Dispassion It's ef core 8 now, and I was just searching for the way to convert color to something storable. So if someone else would look for it too:
in place:
builder.Property(x => x.Color)
.HasConversion(c => c.ToArgb(), i => Color.FromArgb(i))
.IsRequired();
global:
public class ColorToIntConverter : ValueConverter<Color, int>
{
public ColorToIntConverter() : base(v => v.ToArgb(), v => Color.FromArgb(v))
{
}
}
and then in the context:
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
configurationBuilder.Properties<Color>().HaveConversion<ColorToIntConverter>();
}
© 2022 - 2024 — McMap. All rights reserved.