[英]Implementing Zero Or One to Zero Or One relationship in EF Code first by Fluent API
我有两个 POCO 课程:
订单类别:
public class Order
{
int id;
string code;
int? quotationId; //it is foreign key
public int Id{get;set;}
public string Code{get;set;}
public int? QuotationId{get;set;}
Quotation quotation;
public virtual Quotation Quotation { get; set; }
....
}
报价类:
public class Quotation
{
int Id;
string Code;
public int Id{get;set;}
public string Code{get;set;}
Order order;
public virtual Order Order { get; set; }
....
}
Order
可以从一个或零个报价中进行,并且 所以我有一个“一或零”到“一或零”的关系,我如何在Fluent
API 的EF
代码中实现这一点?
通过将 pocos 更改为:
public class Order
{
public int OrderId { get; set; }
public virtual Quotation Quotation { get; set; }
}
public class Quotation
{
public int QuotationId { get; set; }
public virtual Order Order { get; set; }
}
并使用这些映射文件:
public class OrderMap : EntityTypeConfiguration<Order>
{
public OrderMap()
{
this.HasOptional(x => x.Quotation)
.WithOptionalPrincipal()
.Map(x => x.MapKey("OrderId"));
}
}
public class QuotationMap : EntityTypeConfiguration<Quotation>
{
public QuotationMap()
{
this.HasOptional(x => x.Order)
.WithOptionalPrincipal()
.Map(x => x.MapKey("QuotationId"));
}
}
我们将拥有这个 DB(这意味着 0..1-0..1):
特别感谢 ( Vahid Nasiri 先生)
@Masoud 的程序是:
modelBuilder.Entity<Order>()
.HasOptional(o => o.Quotation)
.WithOptionalPrincipal()
.Map(o => o.MapKey("OrderId"));
modelBuilder.Entity<Quotation>()
.HasOptional(o => o.Order)
.WithOptionalPrincipal()
.Map(o => o.MapKey("QuotationId"));
它给:
通过将代码更改为:
modelBuilder.Entity<Order>()
.HasOptional(o => o.Quotation)
.WithOptionalPrincipal(o=> o.Order);
它给:
请参阅http://msdn.microsoft.com/en-us/data/jj591620 EF 关系
一本优秀的书http://my.safaribooksonline.com/book/-/9781449317867
这是 2010 年 12 月开发人员的帖子。但仍然相关http://social.msdn.microsoft.com/Forums/uk/adonetefx/thread/aed3b3f5-c150-4131-a686-1bf547a68804以上文章是一个很好的总结或这里可能的组合。
依赖表具有主表中的键的解决方案是可能的。
如果您想要在 PK/FK 场景中两者都是主体的独立密钥,我认为您无法使用 Fluent API 在 Code first 中做到这一点。 如果他们共享一个密钥,你就可以了。 1:1 可选假设依赖使用来自主要的密钥。
但是因为您需要先保存其中一个表。 您可以使用代码检查其中一个外键。 或者在 Code first 创建之后将第二个 Foreign 添加到数据库中。
你会靠近。 但是如果您希望两者都是外键,EF 会抱怨外键冲突。 本质上 A 取决于 B 取决于 A EF 不喜欢,即使列可以为空并且在 DB 上在技术上是可行的。
这里用这个测试程序来试试。 只需在 Fluent API 内容中发表评论即可尝试一些选项。 我无法让 EF5.0 与 INDEPENDENT PK/FK 0:1 到 0:1 一起工作,但当然有讨论的合理妥协。
using System.Data.Entity;
using System.Linq;
namespace EF_DEMO
{
class Program
{
static void Main(string[] args) {
var ctx = new DemoContext();
var ord = ctx.Orders.FirstOrDefault();
//. DB should be there now...
}
}
public class Order
{
public int Id {get;set;}
public string Code {get;set;}
public int? QuotationId { get; set; } //optional since it is nullable
public virtual Quotation Quotation { get; set; }
//....
}
public class Quotation
{
public int Id {get;set;}
public string Code{get;set;}
// public int? OrderId { get; set; } //optional since it is nullable
public virtual Order Order { get; set; }
//...
}
public class DemoContext : DbContext
{
static DemoContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<DemoContext>());
}
public DemoContext()
: base("Name=Demo") { }
public DbSet<Order> Orders { get; set; }
public DbSet<Quotation> Quotations { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().HasKey(t => t.Id)
.HasOptional(t => t.Quotation)
.WithOptionalPrincipal(d => d.Order)
.Map(t => t.MapKey("OrderId")); // declaring here via MAP means NOT declared in POCO
modelBuilder.Entity<Quotation>().HasKey(t => t.Id)
.HasOptional(q => q.Order)
// .WithOptionalPrincipal(p => p.Quotation) //as both Principals
// .WithOptionalDependent(p => p.Quotation) // as the dependent
// .Map(t => t.MapKey("QuotationId")); done in POCO.
;
}
}
}
改编自这个答案,试试这个。
首先,修复您的课程:
public class Order
{
public int Id {get; set;}
public virtual Quotation Quotation { get; set; }
// other properties
}
public class Quotation
{
public int Id {get; set;}
public virtual Order Order { get; set; }
// other properties
}
然后像这样使用流畅的 API:
modelBuilder.Entity<Quotation>()
.HasOptional(quote => quote.Order)
.WithRequired(order=> order.Quotation);
基本上,对于 1:1 或 [0/1]:[0/1] 关系,EF 需要共享主键。
public class OfficeAssignment { [Key] [ForeignKey("Instructor")] public int InstructorID { get; set; } [StringLength(50)] [Display(Name = "Office Location")] public string Location { get; set; } public virtual Instructor Instructor { get; set; } }
关键属性
Instructor 和 OfficeAssignment 实体之间存在一对零或一的关系。 办公室分配仅与分配给它的讲师相关,因此其主键也是其对 Instructor 实体的外键。 但是实体框架无法自动将 InstructorID 识别为该实体的主键,因为其名称不遵循 ID 或 classnameID 命名约定。 因此,Key 属性用于将其标识为密钥:
使用数据注释:
public class Order
{
[Key]
public int Id {get; set;}
public virtual Quotation Quotation { get; set; }
}
public class Quotation
{
[Key, ForeignKey(nameof(Order))]
public int Id {get; set;}
public virtual Order Order { get; set; }
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.