5

我尝试了一整天来让这个工作。我学到了很多关于 EF 的 Fluent 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, WithOptionalDependent的组合WithOptionalPrincipialUserHouse

protected override void OnModelCreating(DbModelBuilder modelBuilder)

我只是无法让它工作。我想应该很清楚,我想要什么。一个用户可能有多个地址(首先我想强制至少一个,但现在如果用户可以有可选的地址,我会很高兴......)而房子只有一个地址 - 这是必需的。如果房子的地址被级联删除,那就太好了。

4

2 回答 2

4

我相信以下内容应该适合您

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"));
    }
}

请注意,通常最好自己指定外键字段,这可以使您以后的生活更轻松。如果你这样做,那么你可以选择重写House如下:

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

约定将连接 AddressId 和 Address。如果您在 House 和 Address 之间有一对一的映射,您还可以将它们链接到它们的主键上:

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

您提到您希望强制执行至少一个地址 - 这对于一对多关系是不可能的。仅当用户只有一个地址时才能执行此操作,此时您可以在 User 类上添加必需的 AddressId 属性。

另一条评论-您在代码中使所有内容都成为虚拟的。您只需要将导航属性设为虚拟。

于 2012-11-07T08:44:47.183 回答
1

像这样的东西怎么样:

Address对 a强制执行House

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

User在和之间创建一对多关系Address

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

这应该做的是创建一个名为的表UserAddress,将 a 映射UserAddress.

或者,您可以为自己创建一个 POCOUserAddress并修改相关表:

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; }
    ...
}

然后,您将需要以下内容以确保两者User都是Address必需的:

modelBuilder.Entity<UserAddress>().HasRequired(u => u.Address);
modelBuilder.Entity<UserAddress>().HasRequired(u => u.User);
于 2012-11-06T20:14:16.157 回答