【问题标题】:How to make One-To-One relationship with existing fields?如何与现有字段建立一对一关系?
【发布时间】:2013-08-30 19:37:41
【问题描述】:

我有 3 个实体:

  • Foo
  • Bar
  • UniqueFooBar

FooBar 是如下实体:

public class Bar {

   public int Id {get; set;}

   // inverse nav property
   public virtual UniqueFooBar UniqueFooBar {get; set;}

}

public class Foo {

   public string Name {get; set;}

   // inverse nav property
   public virtual UniqueFooBar UniqueFooBar {get; set;}
}

UniqueFooBar 查找如下:

public class UniqueFooBar {

   public string FooName {get; set;}
   public int BarId {get; set;}

   // nav properties
   public virtual Foo Foo {get; set;}
   public virtual Bar Bar {get; set;}

}

具有以下约束:

  • Foo 是独一无二的
  • FooBar 存在一对一的关系
  • Foo名字是PK

    fluent API如下:

    class UniqueFooBarConfiguration : EntityTypeConfiguration<UniqueFooBar> {
        public UniqueFooBarConfiguration() {
            // Define the tablename and schema
            Map(entity => entity.ToTable("UniqueFooBars"));
    
            //// Define non-conventional key
            HasKey(fooBar => fooBar.FooName);
    
            // Define FKs -  1-to-1
            HasRequired(fooBar => fooBar.Foo)
                .WithRequiredPrincipal(foo => foo.UniqueFooBar)
                .Map(key => key.MapKey("FooName"));
            HasRequired(fooBar => fooBar.Bar)
                .WithRequiredPrincipal(bar => bar.UniqueFooBar)
                .Map(key => key.MapKey("BarId"));
            // --------------------------------
    
        }
    
    }
    

发生的情况是FooName 被添加到 Foo 表中并且 BarId 被添加到 Bar 表中。

如果在 UniqueFooBar 的流畅 API 配置中,我尝试使用 Foo 的“名称”属性,那么会出现该字段已存在的错误。如果我尝试使用 Bar 的“Id”属性,也会发生同样的情况。

如何配置 UniqueFooBar 以使 FK 与 Foo.NameBar.Id 成为一对一关系?

更新

  • FooBar 都没有 UniqueFooBar 的约束或要求。
  • UniqueFooBar 记录需要 FooNameBarId

这似乎与How to declare one to one relationship using Entity Framework 4 Code First (POCO)不同

【问题讨论】:

标签: c# .net entity-framework-5


【解决方案1】:

取自here,下面是一个示例,说明如何实现两个实体之间的一对一映射,将其推断为链接表,并根据需要添加 HasRequired。

可以在不使用 lambda 的情况下指定 WithRequiredPrincipal,这允许您排除导航属性并仍然获得正确的一对一映射。

在 OnModelCreating 方法的覆盖中,您可以使用 DBModelBuilder 参数定义您的关系。

public class Customer
{
    public Customer()
    {
        Address = new Address();
    }

    public Guid Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public Guid Id { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Street { get; set; }
}

public  class  CustomerContext : DbContext
{
    public IDbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Customer>()
                .HasRequired(x => x.Address)
                .WithRequiredPrincipal();
         base.OnModelCreating(modelBuilder);
    }
}

【讨论】:

  • 感谢您的额外解释......我想我明白为什么之前事情只是没有工作。如果我理解正确,因为我有一个 forward nav 属性,我不需要在 WithRequiredPrincipal 方法中提供 lambda;这似乎有些混乱。
猜你喜欢
  • 2022-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-11
  • 1970-01-01
  • 1970-01-01
  • 2014-11-22
  • 1970-01-01
相关资源
最近更新 更多