3

我想知道在制作模型时处理关系默认值的最佳方法是什么。(特别是 EF4)

例如,我的组织有一个默认联系人,我想知道哪一个是最好的方法。我有这两个选项(或任何其他人建议如果更好)

使用关系:

public  class Contact
{
    public int Id { get; set; }
    public string FirstName { get; set; }
}

public  class Organization
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Contact> Contacts { get; set; }
    //Use a relationship for the default contact?
    public Contact DefaultContact { get; set; }
}

使用价值:

public  class Contact
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    //Use value?
    public boolean IsDefault { get; set; }
}

public  class Organization
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<Contact> Contacts { get; set; }
}
4

1 回答 1

2

我会选择选项 1。虽然 2 肯定更容易实现,但它不会强制执行诸如“不能有 2 个默认联系人”之类的规则。我最终得到如下内容:

public class Organization {
    // ...
    public virtual ICollection<Contact> { get;set; }
    [ForeignKey("DefaultContactId")]
    public Contact DefaultContact { get;set; }
    public int? DefaultContactId { get;set; }
}

这种方法有一个限制 - 它不适用于嵌套删除(有关更多详细信息,请参阅此问题)。因此,您需要为一对多关系禁用 CascadeOnDelete:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Contact>().HasRequired(co => co.Organization).WithMany().WillCascadeOnDelete(false);
}

(代码未经测试就完成,但应该可以工作)

另一个问题是无法在添加组织的同时添加默认联系人,因为 EF 无法确定正确的语句顺序。您需要在每个之间调用 .SaveChanges。您仍然可以使用 TransactionScope 来克服这个问题,但它并不干净:

using (var ts = new TransactionScope()) 
{
    Organization org = new Organization
    {
        // ...
        Contacts = new Collection<Contact>()
    }
    org.Contacts = new Contact() {};

    orgRepo.SaveChanges();

    // Now wire up the default contact
    org.DefaultContact = org.Contacts.First();
    orgRepo.SaveChanges();
}
于 2012-07-31T16:35:22.653 回答