Entity Framework 5 Code First 中的一对一和一对多关系

问题描述 投票:0回答:3

我一整天都在努力让它工作。我学到了很多关于 EF 的 Fluent API 的知识(例如,this 是一篇很棒的文章),但是我没有成功。

我有三个实体:

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
WithOptionalPrincipial
中的
User
House
的所有组合

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

c# ef-code-first one-to-many entity-framework-5 one-to-one
3个回答
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; } }
Convention将AddressId和Address联系起来。  如果房屋和地址之间有一对一的映射,您还可以在主键上链接它们:

public class House { [ForeignKey("Address")] public int HouseId { get; set; } public virtual Address Address { get; set; } }
您提到您希望强制执行至少一个地址 - 这对于一对多关系是不可能的。  仅当用户只有一个地址时才可以执行此操作,此时您可以在 User 类上添加所需的 AddressId 属性。

另一条评论 - 您在代码中将所有内容都虚拟化了。 您只需将导航属性设为虚拟即可。


1
投票
这样的事情怎么样:

Address

强制执行
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

 的表,将 
User
 映射到 
Address

或者,您可以自己为

UserAddress

 创建 POCO 并修改相关表:

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

0
投票
protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder);

modelBuilder.Entity<Technician>() .HasOne(t => t.Service) .WithMany(t => t.Technicians) .HasForeignKey(t => t.ServiceId) .OnDelete(DeleteBehavior.Restrict);
}

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.