EF模型,包含对特定元素的收集和导航

时间:2016-04-17 20:35:38

标签: entity-framework ef-fluent-api

如何使用具有?

的模型类配置EF6迁移
  • 收集项目
  • 指向某个特定项目的导航属性
public class MyModel
{
    [Key]
    public int Id { get; set; }

    // My collection of elements
    public virtual ICollection<MyCollectionElement> MyCollection { get; set; }

    // Optional navigation to a particular element from the collection
    [ForeignKey("CurrentElement")]
    public int? CurrentElementId { get; set; }

    public virtual MyCollectionElement CurrentElement { get; set; }
}

public class MyCollectionElement
{
    [Key]
    public int Id { get; set; }

    // Required navigation to MyClass
    [ForeignKey("MyModel")]
    public int MyModelID { get; set; }

    public virtual MyModel Model { get; set; }
}

配置

modelBuilder.Entity<MyModel>()
    .HasMany(x => x.MyCollection)
    .WithRequired(x => x.Model)
    .HasForeignKey(x => x.MyModelID)
    .WillCascadadeOnDelete(false);

Update-Database上引发了多个错误,例如

无法确定相关操作的有效排序。

我想要一个不会在 MyCollectionElement 中涉及boolean IsCurrent的解决方案,以便稍后再进行查询并找到哪个元素是当前的;相反,我想将当前元素的id存储到我的模型中,就像暴露一样。

另外,如果它更容易,我不介意int CurrentElementId不可为空(必需)。

感谢。

1 个答案:

答案 0 :(得分:2)

当存在循环关系时,这种鸡蛋问题总是会出现。错误......

  

无法确定相关操作的有效排序。

创建数据库时不会抛出

....数据库可以很好地创建。当您尝试在同一工作单元中插入MyModel记录和MyCollectionElement相互引用时,就会发生这种情况。在Seed方法中,您可能有类似

的内容
var element = new MyCollectionElement();
var model = new MyModel();
model.MyCollection.Add(element);
model.CurrentElement = element;

语句model.MyCollection.Add(element);需要先插入model,因此element可以在其外键中引用它。但model.CurrentElement = element;需要先插入element

您只能通过调用SaveChanges两次来避免这种情况,如果您希望分配是事务性的,则将所有内容包装在TransactionScope中:

using(var ts = new TransactionScope())
{    
    using(var db = new MyContext()
    {
        var element = new MyCollectionElement();
        var model = new MyModel();
        model.MyCollection.Add(element);
        db.MyModels.Add(model);
        db.SaveChanges();

        model.CurrentElement = element;
        db.SaveChanges();
    }
    ts.Complete();
}

这也意味着int CurrentElementId应保持可为空。