C# 将泛型属性与EF一起使用

C# 将泛型属性与EF一起使用,c#,entity-framework,generics,entity-framework-4,metadata,C#,Entity Framework,Generics,Entity Framework 4,Metadata,我知道,但在一个项目中我有一个巨大的需求。。。 我有大约200个包含0到5个复杂泛型属性的类: public class MyCommonProperty { public virtual string Key { get; set; } } public class MyCustomClass<T> : MyCommonProperty where T : struct, IComparable, IFormattable, IConvertible { publ

我知道,但在一个项目中我有一个巨大的需求。。。 我有大约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; }
}

我找不到办法(缺乏知识和技能),因此如果有人有想法或提示,我将不胜感激。

请看一看。您可以使用t4模板生成上下文/存储库等来实现这一点,而不是创建一个通用存储库(尽管如果您查看该页面上生成的类,有一些通用方法)。当您有很多实体类型时,这就消除了一些繁琐的工作。您可以将生成的类创建为
partial
,这样您就可以在另一个分部类中添加其他功能,而无需直接修改生成的代码。我无法使用T4生成我的类,因为它们位于单独的程序集中,并由另一个团队维护:edmx和DbContext位于DAL命名空间和解决方案中,POCO位于域名称空间和解决方案中。我不想使用泛型方法,而是使用getter和setter的泛型属性,以避免在近500个属性中重复和维护相同的代码(大约100行)。。。唯一的问题是在ObjectContext.MetadataWorkspace中找到一种复制然后重命名条目的方法实际上不需要EDMX来使用t4模板(请参阅的教程部分)。我确实遇到了另一种方法,它使用反射来后期绑定EDM(看起来确实值得一读)。这似乎也是使用依赖注入进行上下文绑定的候选方法(类似于这样),但我需要对此进行更多的思考。除非我弄错了,否则您建议在我的域解决方案中构建一个T4模板,使用它解析DAL edmx(实际上是xml)文件以查找所有声明的类型(因为我使用POCO,所以没有生成类:不可能进行反射),然后生成大量的分部类我对此解决方案有两个问题:-我将无法在我的类及其属性上添加注释,或者每次运行T4时这些注释将被删除-所有类将在单个名称空间中生成,但我需要它们位于不同的名称空间、子名称空间中,根据一些B除非我弄错了,否则您建议在我的域解决方案中构建一个T4模板,使用它来解析DAL edmx(实际上是xml)文件来查找声明的所有类型t4可能不合适,但在最后的评论中,我只是指出使用t4不需要EDMX。另外,我建议您研究一下这个问题。
所有类都将在一个名称空间中生成,但我需要它们位于不同的名称空间、子名称空间中,根据一些B业务逻辑
请参阅我之前关于Ninject上下文绑定的评论。
using (var db = new ModelContainer())
{
    db.ConcreteClassSet.AddObject(new ConcreteClass()
    {
        CustomType1 = new MyCustomClass<CustomType1>() { Key = "RandomKey1" },
        CustomType2 = new MyCustomClass<CustomType2>() { Key = "RandomKey2" }
    });
    db.SaveChanges();
}
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; }
}
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);