我在另一个互连的VS项目中使用了多个类,例如:
namespace MyOtherProject
{
public class A {
public string Name {get;set;}
}
public class B {
public int Value {get;set;}
public A Child {get;set;}
}
}
现在我想首先在EF中将这些类用作代码的POCO。但是我不需要数据库中的所有类,只需要其中的一些。所以我创建了一个上下文:
public class MyContext : DbContext
{
public MyContext () : base("MyContext ")
{
}
public DbSet<B> Bs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
当我尝试运行项目时,我收到此错误:
System.Data.Entity.ModelConfiguration.ModelValidationException:一个或 在模型生成期间检测到更多验证错误: MyProject.A:名称:架构中的每个类型名称必须是唯一的。类型 名称'A'已定义。
请注意,错误中的命名空间与A类的定义不同,因为我的A类是在另一个(共享)项目中定义的。相反,命名空间是上下文之一。
您可以省略DbSet和DbSet 声明,它将工作相同。实体框架会 隐式包含它们,因为Student实体引用了 注册实体和注册实体引用课程 实体。
我的假设(未确认)是EF看到B引用A但没有类型A的数据集,因此它在内部生成A类,然后突然发现有两个这样的类。
任何人都知道确切的问题是什么以及我可以做些什么来解决它?我有太多我不需要的课程,所以我不想为每个课程创建数据集。
答案 0 :(得分:2)
首先,从Type1
获取所有泛型类型参数(Type2
,DbSet<Type1>
...)。然后你应该检查每种类型的内部属性类型,即对其他类型的引用(作为直接链接或通过ICollection
集), - 如果这个内部类型不存在于第一个 tablesTypes 我们会忽略它们。
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//other stuff.....
Func<Type, bool> genericFilter = x => typeof(IEnumerable).IsAssignableFrom(x) && x.GenericTypeArguments.Length == 1;
//All types of your context tables
var tablesTypes = GetType().GetProperties()
.Where(x => genericFilter(x.PropertyType))
.Select(x => x.PropertyType.GenericTypeArguments.First());
var namespaces2ignore = new List<string> { "Namespace2Ignore1", "Namespace2Ignore2" };
var toIgnore = new List<Type>();
foreach (var type in tablesTypes)
//Ignore internal types, which not exist at tablesTypes
toIgnore.AddRange(type.GetProperties()
.Select(x => genericFilter(x.PropertyType) ? x.PropertyType.GenericTypeArguments.First() : x.PropertyType)
.Where(x => !tablesTypes.Contains(x) && namespaces2ignore.Contains(x.Namespace)
/*or as you suggested: && typeof(A).Assembly == x.Assembly*/
).ToList());
modelBuilder.Ignore(toIgnore);
}
如果要在特定对类型属性上添加条件,可以执行以下操作:
foreach (var type in tablesTypes)
foreach(var prop in type.GetProperties()
.Select(x => new { type = genericFilter(x.PropertyType) ? x.PropertyType.GenericTypeArguments.First() : x.PropertyType, prop = x })
.Where(x => !tablesTypes.Contains(x.type) && namespaces2ignore.Contains(x.type.Namespace)
).ToList())
if(!(type == typeof(TestType) && prop.prop.Name == "Test"))
toIgnore.Add(prop.type);
现在不会被排除在名称&#34;测试&#34;&#34;类型为TestType
。