我目前正在学习ASP.NET MVC和Web API。
我正在尝试创建用户模型。用户可以拥有任意数量的UserContacts。 UserContacts引用用户作为联系人的用户和作为联系人的用户。我创建了一个名为UserContact的模型,因为附加到此模型是附加信息。
public class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class UserContact
{
public int UserContactID { get; set; }
public int UserID { get; set; }
[ForeignKey("UserID"), Column(Order = 0)]
[Required]
public User User { get; set; }
public int ContactID { get; set; }
[ForeignKey("ContactID"), Column(Order = 1)]
[Required]
public User Contact { get; set; }
public DateTime ContactSince { get; set; }
}
所以这给我一个错误,指的是级联删除。如何设置这样的关系,其中两个外键指向相同的模型类型?我还没有掌握实体框架语法。如果我在User模型中没有UserContacts的ICollection,这是否会阻碍我获取与该用户关联的UserContacts的能力?
答案 0 :(得分:1)
当您有外键并且外键列不可为空时(表示必需)。 EF将自动尝试在relationshipip上启用级联删除。在您的情况下,它将尝试为两个外键列启用级联删除,并且它们都指向同一个用户表!这就是你得到这个错误的原因。如果您有一个User UserId
和ContactID
的UserContact记录指向同一个用户记录,该怎么办?级联删除现在很困惑:)
此外,由于一个用户可以拥有多个联系人,因此我们需要在User表上使用Contacts属性来表示该联系人。这将是UserContact的集合。此用户也可以是许多其他人的联系人。所以让我们为此创建另一个属性。
public class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<UserContact> Contacts { set; get; }
public ICollection<UserContact> ContactOf { set; get; }
}
public class UserContact
{
public int UserContactID { get; set; }
public int UserID { get; set; }
public User User { get; set; }
public int ContactID { get; set; }
public User Contact { get; set; }
public DateTime ContactSince { get; set; }
}
在你的DbContext类中,我们可以配置外键关系并告诉EF在重写的OnModelCreating
方法中使用fluent配置禁用级联删除。以下代码将禁用两个关系上的级联删除。但是你的错误消失了。禁用一个外键就足够了。
public class YourDbContext: DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<UserContact>()
.HasRequired<User>(g=>g.User)
.WithMany(g=>g.Contacts)
.HasForeignKey(g=>g.UserID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<UserContact>()
.HasRequired<User>(g => g.Contact)
.WithMany(g => g.ContactOf)
.HasForeignKey(g => g.ContactID)
.WillCascadeOnDelete(false); // this one is not really needed to fix the error
base.OnModelCreating(modelBuilder);
}
public DbSet<User> Users { set; get; }
public DbSet<UserContact> UserContacts { set; get; }
}
答案 1 :(得分:0)
EF没有足够的信息来确定另一方的关系,所以是的,你需要收藏。您可以使用InverseProperty批注来阐明(或流畅的api语句):
public class User
{
public int UserID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
[InverseProperty("User")]
public Virtual ICollection<UserContact> Users{ get; set; }
[InverseProperty("Contact")]
public Virtual ICollection<UserContact> Contacts { get; set; }
}
public class UserContact
{
public int UserContactID { get; set; }
public int UserID { get; set; }
[ForeignKey("UserID"), Column(Order = 0)]
[Required]
public User User { get; set; }
public int ContactID { get; set; }
[ForeignKey("ContactID"), Column(Order = 1)]
[Required]
public User Contact { get; set; }
public DateTime ContactSince { get; set; }
}