这两个一到一和一到许多实体框架5码首先关系(Both One-To-One and One-To-M

2019-07-03 15:16发布

我想了整整一天得到这个工作。 我学到了很多关于EF的流畅API(例如, 这是一个很好的文章),但我没有成功。

我有三个实体:

public class Address
{
   [Key]
   public virtual int AddressId { get; set; }
   public virtual string AddressString { get; set; }
}
public class User
{
   [Key]
   public virtual int UserId { get; set; }
   public virtual ICollection<Address> Addresses { get; set; }
}
public class House
{
   [Key]
   public virtual int HouseId { get; set; }
   public virtual Address Address { get; set; }
}

并试图的所有组合HasMany, HasOptional, WithOptional, WithOptionalDependentWithOptionalPrincipial我能想到的两个UserHouse

protected override void OnModelCreating(DbModelBuilder modelBuilder)

我只是无法得到它的工作。 我觉得应该是清楚的,我想要什么。 用户可能有多个地址(在我想迫使至少一个第一名,但现在我会很高兴,如果用户可能具有的地址选......),而一套房子只能有一个地址 - 这是需要。 如果一所房子的地址将被删除级联这将是很好。

Answer 1:

我认为以下应为你工作

public class Address
{
    public int AddressId { get; set; }
    public string AddressString { get; set; }
}

public class User
{
    public int UserId { get; set; }
    public virtual ICollection<Address> Addresses { get; set; }
}

public class House
{
    public int HouseId { get; set; }
    public virtual Address Address { get; set; }
}

public class TestContext : DbContext
{
    public DbSet<Address> Addresses { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<House> Houses { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany();
        modelBuilder.Entity<House>().HasRequired(h => h.Address).WithOptional().Map(m => m.MapKey("AddressId"));
    }
}

请注意,它往往是更好的给自己指定的外键的字段,它可以使生活变得更加简单了,你以后。 如果你这样做,那么你可以选择重写阁为以下几点:

public class House
{
    public int HouseId { get; set; }
    public int AddressId { get; set; }
    public virtual Address Address { get; set; }
}

公约将连接AddressId和地址。 如果你有房子和地址之间有一个一对一映射,你也可以将它们链接在他们的主键:

public class House
{
    [ForeignKey("Address")]              
    public int HouseId { get; set; }
    public virtual Address Address { get; set; }
}

你提到你想执行至少一个地址 - 这是不可能与一个一对多的关系。 你只能这样做,如果用户有只有一个地址,此时你可以对用户类添加所需的AddressId属性。

另一种意见 - 你做一切都在你的代码的虚拟。 你只需要进行导航属性的虚拟。



Answer 2:

什么是这样的:

强制执行的AddressHouse

modelBuilder.Entity<House>().HasRequired(d => d.Address);

之间创建一个一对多的关系, UserAddress

modelBuilder.Entity<User>().HasMany(u => u.Addresses).WithMany().Map(x =>
{
    x.MapLeftKey("UserId");
    x.MapRightKey("AddressId");
    x.ToTable("UserAddress");
});

这是什么应该做的是创建一个名为表UserAddress一个映射User到一个Address

或者,你可以创建一个POCO UserAddress自己和修改有关的表格:

public class UserAddress
{
    [Key]
    public int UserAddressId { get; set; }
    public User User { get; set; }
    public Address Address { get; set; }
}

public User
{
    ...
    public virtual ICollection<UserAddress> UserAddresses { get; set; }
    ...
}

public Address
{
    ...
    public virtual ICollection<UserAddress> UserAddresses { get; set; }
    ...
}

然后,您将需要以下,以确保双方UserAddress是必需的:

modelBuilder.Entity<UserAddress>().HasRequired(u => u.Address);
modelBuilder.Entity<UserAddress>().HasRequired(u => u.User);


文章来源: Both One-To-One and One-To-Many relationships in Entity Framework 5 Code First