为什么Entity Framework只在一个集合中级联单个项目?

时间:2013-08-07 02:39:32

标签: entity-framework entity-framework-5 cascade

我有一个Code First EF 5.0模型,它具有以下结构:

public class Widget 
{
    public virtual Int32 Id { get; set; }
    public virtual String Name { get; set; }
}

public class Product
{
    public virtual Int32 Id { get; set; }
    public virtual ICollection<Widget> Widgets { get; set; }
    public virtual AddWidget(Widget widget)
    {
        Guard.NotNull(widget);

        if (Widgets == null)
        {
            Widgets = new List<Widget>();
        }

        Widgets.Add(widget);
    }
}

当我尝试保存添加了多个Product的新短暂Widget时,只保存添加的第一个Widget

// ProductManagementContext is a DbContext
// ProductManagementContext.Products is a DbSet<Product>
using(var context = new ProductManagementContext())  
{
    var product = new Product();
    product.AddWidget(new Widget() { Name = "Foo" } );
    product.AddWidget(new Widget() { Name = "Bar" } );
    context.Products.Add(product);
    context.SaveChanges();
}

此时,只有&#34; Foo&#34;存在于Widget表中。我使用SQL Server Profiler检查进入数据库的数据,并且只为集合中添加了两个INSERT的{​​{1}}发出了一个Widget语句。

为什么EF不会在两个新实体上级联?

2 个答案:

答案 0 :(得分:1)

使用给定的代码无法重现您的问题。我已经复制并粘贴了它,修复了编译问题(AddWidget需要返回类型),删除了对Guard的调用,运行它并看到数据库中都出现了Widgets。

这是完整的代码。希望你能发现代码的不同之处。

using System;
using System.Collections.Generic;
using System.Data.Entity;

namespace EF_SO_Q
{
    class Program
    {
        static void Main(string[] args)
        {
            using (var context = new ProductManagementContext())
            {
                var product = new Product();
                product.AddWidget(new Widget() { Name = "Foo" });
                product.AddWidget(new Widget() { Name = "Bar" });
                context.Products.Add(product);
                context.SaveChanges();
            }
        }
    }

    public class Widget
    {
        public virtual Int32 Id { get; set; }
        public virtual String Name { get; set; }
    }

    public class Product
    {
        public virtual Int32 Id { get; set; }
        public virtual ICollection<Widget> Widgets { get; set; }
        public virtual void AddWidget(Widget widget)
        {

            if (Widgets == null)
            {
                Widgets = new List<Widget>();
            }

            Widgets.Add(widget);
        }
    }

    public class ProductManagementContext : DbContext
    {
        public DbSet<Widget> Widgets { get; set; }
        public DbSet<Product> Products { get; set; }
    }
}

答案 1 :(得分:0)

我不确定,但我认为这是因为id中的虚拟关键字。

你首先说它是代码,db中的键代表一个不可变属性。允许覆盖该参数会令人困惑,并且可能不正确......

此外,子元素列表定义为跟随this.Widgets = new HashSet<Widget>();更为通用的列表...我会试一试

P.S。我先用过模特