模型第一:如何添加 Color 类型的属性?

问题描述 投票:0回答:3

我正在使用模型优先方法创建一个新数据库,我想向

System.Drawing.Color
类型的表添加一列,但属性列表中没有此选项。

有没有办法使用比可用数据类型更多的数据类型?

c# entity-framework ef-model-first
3个回答
17
投票

此处的另一个选项是使用 Entity Framework 6 Code First - 自定义类型映射

中的答案
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; }
}

NotMapped
属性使实体框架不会尝试将 Color 属性映射到数据库中的列。


3
投票

这里的一个选择是拥有 ARGB 颜色的

int
版本:

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;
      }
   }
}

在映射中,通过使用连贯绑定专门忽略

Color
属性:

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");
}

从这里您现在可以存储来自任何 Color 静态方法的数据:

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 );

注释中选择的一种替代方法是序列化为 XML。

上面的代码使用整数,因为它使用 SQL Server 原生、高效的数据类型,并且易于维护。

XML 版本会占用更多空间,不易维护,并且现在会增加搜索特定颜色的复杂性。扩展的

System.Drawing.Color
类型如下所示:

<Color>
    <A>123</A>
    <R>45</R>
    <G>67</G>
    <B>89</B>
    <ScA>0.482352942</ScA>
    <ScR>0.026241‌​2224</ScR>
    <ScG>0.0561284944</ScG>
    <ScB>0.09989873</ScB>
</Color>

蓝色哪个更容易搜索?

对于

int
类型,这将是:

SELECT COUNT(1) FROM Customer cust
INNER JOIN Color col
ON cust.FavouriteColorId = color.Id
WHERE col.Argb = 0xFF0000FF

对于 XML 类型:

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'

0
投票

现在是ef core 8, 我只是在寻找将颜色转换为可存储内容的方法。 所以如果其他人也会寻找它:

到位:

builder.Property(x => x.Color)
    .HasConversion(c => c.ToArgb(), i => Color.FromArgb(i))
    .IsRequired();

全球:

public class ColorToIntConverter : ValueConverter<Color, int>
{
    public ColorToIntConverter() : base(v => v.ToArgb(), v => Color.FromArgb(v))
    {
    }
}

然后在上下文中:

protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
    configurationBuilder.Properties<Color>().HaveConversion<ColorToIntConverter>();
}
© www.soinside.com 2019 - 2024. All rights reserved.