Entity framework EF6:表拆分不起作用
我正在尝试创建一个EF6数据库,其中两个表,地址和访问,与主键共享相同的值。从概念上讲,访问是地址的扩展。我之所以拆分表,是因为地址中的大多数记录不需要访问中包含的字段 我使用的是代码优先的方法。以下是地址的相关代码:Entity framework EF6:表拆分不起作用,entity-framework,entity-framework-6,table-splitting,Entity Framework,Entity Framework 6,Table Splitting,我正在尝试创建一个EF6数据库,其中两个表,地址和访问,与主键共享相同的值。从概念上讲,访问是地址的扩展。我之所以拆分表,是因为地址中的大多数记录不需要访问中包含的字段 我使用的是代码优先的方法。以下是地址的相关代码: public class Address { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int ID { get; set; } [Foreig
public class Address
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[ForeignKey( "ID" )]
public virtual Visit Visit { get; set; }
访问:
public class Visit
{
[Key]
[DatabaseGenerated( DatabaseGeneratedOption.Identity )]
public int ID { get; set; }
[ForeignKey("ID")]
public virtual Address Address { get; set; }
根据我的研究,我还需要在datacontext的OnModelCreating方法中包括以下内容:
modelBuilder.Entity<Visit>()
.HasOptional( v => v.Address )
.WithRequired();
modelBuilder.Entity()
.has可选(v=>v.地址)
.WithRequired();
不幸的是,这不起作用。在消除了从地址中删除主索引的脚手架调用(可能是因为add迁移代码认为主键“仅仅”是一个外键字段)之后,我可以更新数据库。但当我运行应用程序时,会出现以下错误:
无效的列名“地址\ ID”。
无效的列名“地址\ ID”
从我对EF6的有限经验来看,这看起来像是框架内部的某个地方,它希望在Visits表中有名为“Address_ID”的字段(基于我看到的其他隐式添加字段的“table name”和“field name”命名结构)
我想做的事可能吗?如果是,配置中缺少什么
其他信息
在尝试bubi提出的解决方案时(不幸的是,该解决方案仍然会生成相同的错误),我可以消除onmodel创建代码,并仍然生成功能迁移代码
分辨率
我终于做了我之前应该做的事情,那就是检查由正在爆炸的查询生成的实际T-SQL代码。原来问题不在访问/地址链接中,而是在涉及另一个表的完全独立的关系中。显然,在这一过程中,我做了一些事情,使EF认为其他表(选民)有一个Address_ID外键字段。实际上,地址/投票者关系本来应该和Voter.AddressID字段绑定
我没有尝试展开大量的迁移,而是选择吹走数据库,吹走迁移,从头开始。在重新创建了数据库之后——但使用了bubi的建议——我从备份中重新加载了数据,瞧,我又回到了业务中
为了完整起见,下面是我最后不得不放入OnModelCreating方法调用的代码,以使地址/访问关系正常工作:
modelBuilder.Entity<Visit>()
.HasRequired( v => v.Address )
.WithRequiredDependent( a => a.Visit );
modelBuilder.Entity<Address>()
.HasRequired( a => a.Visit )
.WithRequiredPrincipal( v => v.Address );
modelBuilder.Entity()
.HasRequired(v=>v.地址)
.需要依赖(a=>a.访问);
modelBuilder.Entity()
.HasRequired(a=>a.访问)
.具有所需的委托人(v=>v.地址);
我有点困惑为什么我必须使用HasRequired才能使用WithRequiredPrincipal/WithRequiredDependent,因为不是地址表中的每个条目都在访问表中有条目。这似乎是“可选的”,而不是“必需的”。但它似乎是可行的,可能“必需”部分只是EF数据库模型的内部部分,而不是数据库本身。模型中有两个问题:
-只有一个键可以自动编号,另一个键必须具有相同的Id(这由EF独立完成)。
-映射问题。
这种模式应该行得通
public class Address
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Description { get; set; }
public virtual Visit Visit { get; set; }
}
public class Visit
{
public Visit()
{
Address = new Address();
}
[Key]
[ForeignKey("Address")]
public int Id { get; set; }
public string Description { get; set; }
public virtual Address Address { get; set; }
}
使用示例
var visit = new Visit
{
Description = "Visit",
Address = {Description = "AddressDescription"}
};
db.Visits.Add(visit);
db.SaveChanges();
除了bubi提到的内容之外,您的
modelBuilder
语句与模型相矛盾,因为它没有提到地址。请访问作为反向属性。因此,它认为该属性表示一个单独的关系,并尝试为该关系创建Address\u ID
列
你需要有
modelBuilder.Entity<Visit>()
// from your description sounds like every Visit needs an Address
.HasRequired(v => v.Address )
// need to mention the inverse property here if you have one
.WithOptional(a => a.Visit);
modelBuilder.Entity()
//根据你的描述,似乎每次访问都需要一个地址
.HasRequired(v=>v.地址)
//如果你有逆属性的话,需要在这里提到逆属性
.可选(a=>a.Visit);
…或者完全删除该语句,因为您已经在使用属性,EF应该能够按照约定解决它。Thanx回答,但它不起作用。仍然会生成相同的运行时错误(投诉无法找到标有“Address_ID”的列,EF可能正在访问表中查找该列。我更新了我的问题,以包含有关调用modelBuilder的更多信息。我在运行代码后发送了代码。尝试删除数据库并再次运行代码。