在EF中使用Generics属性

时间:2013-01-08 15:04:03

标签: c# entity-framework generics entity-framework-4 metadata

我知道EF isn't supposed to support generic Entity types但我对项目有很大的需求...... 我有大约200个包含0到5个复杂通用属性的类:

public class MyCommonProperty
{
    public virtual string Key { get; set; }
}

public class MyCustomClass<T> : MyCommonProperty where T : struct, IComparable, IFormattable, IConvertible
{
    public virtual T Value { get; set; }
    public virtual string DisplayValue { get; set; }

    public MyCustomClass(string key)
    {
        Key = key;
    }
}

public class ConcreteClass
{
    public int Id { get; set; }
    public MyCustomClass<CustomType1> CustomType1 { get; set; }
    public MyCustomClass<CustomType2> CustomType2 { get; set; }
}

我只想使用这些POCO在具有实体框架的数据库中保留 Key 属性。 这是我的模特:

  • 实体类型
    • 具体类
      • Id( int ,Identity)
      • CustomType1( MyCommonProperty
      • CustomType2( MyCommonProperty
  • 复杂类型
    • MyCommonProperty
      • 键(字符串

最后,在我的UI中,代码如下:

using (var db = new ModelContainer())
{
    db.ConcreteClassSet.AddObject(new ConcreteClass()
    {
        CustomType1 = new MyCustomClass<CustomType1>() { Key = "RandomKey1" },
        CustomType2 = new MyCustomClass<CustomType2>() { Key = "RandomKey2" }
    });
    db.SaveChanges();
}

当我运行此代码时,我收到此错误:

  

具有身份的成员   'Domain.MyCustomClass`1 [[Domain.CustomType1,Domain,   Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]]'没有   存在于元数据集合中。

虽然我的edmx中没有定义 MyCustomClass ,但我不会关心这个类,因为 MyCustomClass 也是 MyCommonProperty wich在元数据中定义......

我在我的容器中覆盖了 ValidateEntity

public partial class ModelContainer : DbContext
{
    public ModelContainer()
        : base("name=ModelContainer")
    {
    }

    protected override DbEntityValidationResult ValidateEntity(DbEntityEntry entityEntry, IDictionary<object, object> items)
    {
        if (entityEntry.Entity is ConcreteClass)
            return new DbEntityValidationResult(entityEntry, new List<DbValidationError>());
        return base.ValidateEntity(entityEntry, items);
    }

    public DbSet<ConcreteClass> ConcreteClassSet { get; set; }
}

基本上,我关闭了 ConcreteClass 的验证,告诉EF它们始终有效。 通过此解决方法, db.Save()工作:在数据库中,添加了一个新行,在 CustomType1 和 CustomType2 字段。

现在问题是验证:我不想关闭包含这些泛型属性的所有实体的验证 看起来唯一的问题是Entity在元数据中搜索我的属性的具体类型( MyCustomClass )并且找不到它,因为在那里声明的唯一类型是 MyCommonProperty

我认为通过修改元数据可以在其中添加一些假类型。 例如,通过找到 MyCommonProperty ,复制它,并重命名副本'Domain.MyCustomClass`1 [[Domain.CustomType1,Domain,Version = 1.0.0.0,Culture = neutral,PublicKeyToken =空]]'

var metadata = (this as IObjectContextAdapter).ObjectContext.MetadataWorkspace;
var metaType = metadata.GetType("MyCommonProperty", "Domain", DataSpace.CSpace);
metaType.Name = "'Domain.MyCustomClass`1[[Domain.CustomType1, Domain, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]'";
metadata.RegisterItemCollection(metaType);

我无法找到一种方法(缺乏知识和技能),所以如果有人有想法或提示,我将不胜感激。

0 个答案:

没有答案