实体框架 - Fluent API映射

时间:2016-02-26 01:32:09

标签: c# entity-framework ef-fluent-api

public class Customer
{
    public int Id { get; set; }

    public int AddressId { get; set; }

    public virtual Address { get; set; }
}

public class Address
{
   public int Id { get; set; }

   public virtual Customer { get; set; }
}

客户必须强制要求地址。地址可能有也可能没有客户。 Address中的Customer导航属性类似于“可空”。我在Customer.AddressId表中有一个唯一的索引。

有没有办法使用流畅的API进行映射?

编辑:

CREATE TABLE Address
(
    Id           INT NOT NULL IDENTITY PRIMARY KEY,
    AddressLine1 VARCHAR(50),
)

CREATE TABLE Customer
(
     Id         INT NOT NULL IDENTITY PRIMARY KEY,
     Name       VARCHAR(50) NOT NULL,
     AddressId  INT NOT NULL,
     CONSTRAINT FK_Customer_Address FOREIGN KEY(AddressId) REFERENCES Address (Id)
)

2 个答案:

答案 0 :(得分:1)

我重新创建了整个数据库和模型,并且能够将记录添加到客户和地址表中。

基本上,如果客户只能拥有一个地址,那么这意味着一个地址可以拥有0个或更多客户。 (不是0或1)理想。 但由于您的唯一性限制,地址总是最终只有0或1个客户记录。但这是一个运行时约束,EF在设计时并不知道这一点。 (我认为它无法完全掌握双向关系的唯一性规则)EF会将Address-to-Customer建模为0:N,并让运行时处理N永远不会超过1的事实。

这是因为想到了记录。

  1. customerA记录,需要有一个AddressA记录
  2. 可以将AddressB记录独立地插入到地址表中。
  3. Customer表中的另一个CustomerC记录必须具有地址记录,并且此记录必须是AddressB或AddressC。 (由于唯一索引约束,它不能是AddressA)
  4. 可以将AddressD记录独立地插入到地址表中。
  5. 因此,AddressA有1条客户记录,AddressD有0条客户记录。

    现在的问题是,您的SQL服务器知道客户记录只能有一个地址记录,并且该地址记录必须是唯一的。

    EF无法理解双向意义上的唯一性部分。它知道客户只需要一个地址,但不能强制要求该地址必须是唯一的。如果您尝试插入一个已经属于另一个客户的地址的客户,则当底层INSERT抛出错误时,自然会发生此错误。由于唯一性约束,EF实际上在创建模型方面做得很好,客户和地址之间的比例为1:1。

    但是因为它不能双向理解唯一性部分,所以它将多个客户映射到一个地址。 (0个或更多客户,而不是0或1)

    所以你的映射需要看起来像这样:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Address>()
                .HasMany(e => e.Customers)
                .WithRequired(e => e.Address)
                .WillCascadeOnDelete(false);
        }
    

    这确保了客户始终具有所需的地址实体,并且地址具有0个或更多客户。 (实际上,由于唯一性约束,您最终只能在该列表中使用0或1个客户),但您无法在EF中强制执行。你需要总是获取List<Customers>,它总是会有0或1个元素。

    如果您尝试手动修改映射并且在Address和Customer之间有一个可选的0:1关系(而不是0:N),那么EF会有点混淆并因某种原因开始抛出IDENTITY插入异常。不知道为什么。

    所以你可以使用上面的映射,确保你在List<Customers>

    中始终只有0或1条记录。

    已经有功能要求完全理解双方的唯一性方面(转换为我认为的良好感知的关系代数)。 https://data.uservoice.com/forums/72025-entity-framework-feature-suggestions/suggestions/1050579-unique-constraint-i-e-candidate-key-support

答案 1 :(得分:-1)

public class Customer
{
    public int Id { get; set; }
    public Address { get; set; }
}
public class Address
{
   public int Id { get; set; }
   public int? CustomerId { get; set; }
   public virtual Customer { get; set; }
}