Entity Framework7:识别关系

Entity Framework 7: Identifying relationships

在早期版本的 EF 中,我可以使用以下代码来实现标识关系:

public class Child
{
    [Key, Column(Order = 1)]
    public virtual int Id { get; set; }

    [Key, Column(Order = 2)]
    public virtual int ParentId { get; set; }
    public virtual Parent Parent { get; set; }
}

需要像这样轻松地从集合中删除子项:

var parent = _context.Parents.First();
var child = parent.Children.First();

parent.Children.Remove(child);

_context.SaveChanges();

http://www.kianryan.co.uk/2013/03/orphaned-child/(方法 #2)中描述了这种方法。

但在 EF7 中,此代码在创建迁移时抛出异常:

An exception was thrown while executing a resolve operation. See the InnerException for details. ---> Entity type 'Child' has composite primary key defined with data annotations. To set composite primary key, use fluent API.

我还尝试按照 How to define nested Identifying Relationships Entity Framework code first 中所述在以下代码中使用 FluentAPI:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Parent>()
            .HasMany(p => p.Children)
            .WithOne(c => c.Parent);

        modelBuilder.Entity<Child>()
            .HasKey(c => new {c.Id, c.ParentId});

        base.OnModelCreating(modelBuilder);
    }

这种方法允许成功生成迁移,但是当我尝试从 Children 集合中删除一个子项时,出现以下异常:

System.InvalidOperationException: The association between entity types 'Parent' and 'Child' has been severed but the foreign key for this relationship cannot be set to null. If the dependent entity should be deleted, then setup the relationship to use cascade deletes.

但我不想使用级联删除,我想使用识别关系!

请帮助我理解我做错了什么。谢谢!

改为使用级联删除,因为它的用途是:

modelBuilder.Entity<Parent>()
    .HasMany(p => p.Children)
    .WithOne(c => c.Parent);
    .WillCascadeOnDelete(true);

https://msdn.microsoft.com/en-gb/data/jj591620.aspx

以防万一有人看到这个错误,让我告诉你我是如何解决我的错误的:

当你进行更新时,在 EF 上你需要首先查询数据库并获取数据模型,然后将你的更改映射到域层模型上(基本上是将字段复制到数据上),最后调用DBContext 更新方法,然后保存更改。

我的问题是我的模型(不是数据模型,领域模型)也有子对象。

所以这是数据层模型(例如):

public class Parent
{
   public int ChildId {get; set; }

   [ForeignKey("ChildId")]
   public virtual Child Child { get; set; }
}

领域层模型应该是这样的:

public class Parent
    {
        public int ChildId { get; set; }
        //public Child Child { get; set; }  // this caused the error, keep reading if you want to know more.
    }

当我看到错误时,我一直在使用 Autofac 的运行时映射器将域层模型的属性映射到数据层模型。但是domain层model中的child是null,所以会把数据层null掉,导致报错:

"The association between entity types 'Parent' and 'Child' has been severed but the foreign key for this relationship cannot be set to null. If the dependent entity should be deleted, then setup the relationship to use cascade deletes."


顺便说一下,在数据库上下文 class 中,我定义了以下关系:

modelBuilder.Entity<Parent>()
   .HasOne(a => a.Child)
   .WithMany()
   .HasForeignKey(p => p.ChildId)
   .OnDelete(DeleteBehavior.Restrict);

有效。