实体框架更新:存储更新,插入或删除语句影响了意外的行数

时间:2017-11-01 05:54:39

标签: c# mysql entity-framework

我有以下型号: -

    public abstract class BaseClass
        {
            [Key]
            [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
            public Guid Id
            {
                get;
                set;
            }protected BaseClass()
            {
                if (Guid.Empty==Id)
                {
                    Id = LongGuid.NewGuid();

                }
            }
        }
    }

    public class Product : BaseClass
        {

          // other properties like name and price.
          private Recipe _recipe;
            public virtual Recipe Recipe
            {
                get
                {    
                    return this._recipe;
                }
                set
                {
                    this._recipe = value;
                }
            }

            private InventoryItem _inventoryItem;
            public virtual InventoryItem InventoryItem
            {
                get
                {
                    return this._inventoryItem;
                }
                set
                {
                    this._inventoryItem = value;
                }
            }
public class InventoryItem  : BaseClass
{
 // Name and value 
}

public class Recipe : BaseClass
{
 // Name and value 
}
public class DataContext : DbContext
{
    public DbSet<Recipe> Recipes { get; set; }
    public DbSet<InventoryItem> InventoryItems { get; set; }
    public DbSet<Product> Product { get; set; }
}

我保存如下: -

this._workspace.Update(Model);
this._context.SaveChanges();

当我用InventoryItem和Recipe创建产品时,它的效果很好。

但是当我创建没有InventoryItem和Recipe的产品并保存在数据库中之后我尝试使用新的InventoryItem()和新的Recipe()更新产品时出现以下错误: -

  

保存不公开外键的实体时发生错误   他们关系的属性。 EntityEntries属性将   返回null,因为无法将单个实体标识为源   例外。可以在保存时处理异常   通过在实体类型中公开外键属性更容易。看到   InnerException以获取详细信息。

内部错误: -

  

存储更新,插入或删除语句会影响意外   行数(0)。自那以后,实体可能已被修改或删除   实体已加载。看到   http://go.microsoft.com/fwlink/?LinkId=472540了解有关的信息   理解和处理乐观并发异常。

1 个答案:

答案 0 :(得分:1)

您收到此错误的原因是,EF无法确定如何将您的产品与您的配方和InventoryItem相关联。要解决此问题,请暂时删除您的InventoryItem,并按预期保持产品和配方的持久性。

使用EF 6和Core,您可以选择在父实体中定义FK字段,并将其指定为您引用的子实体的FK。

例如,使用代码优先注释:

public class Product
{
   [Key]
   public Guid ProductId {get; set;}

   [ForeignKey("RecipeId")]
   public virtual Recipe Recipe {get; set;}

   public Guid RecipeId {get; set;}

   // ...
}

或者,您可以通过实体类型配置使用配置或覆盖DbContext的OnModelCreating以使用.HasForeignKey()流畅方法建立外键。

如果您不小心,以这种方式映射FK可能会引发问题,因为您现在已经引用了食谱实体和单独的FK引用,并且必须确保它们保持同步。

或者使用EF 6,您可以映射FK的列,而不使用实体类型配置中的.Map()/ w .MapKey()或DbContext的OnModelCreating来声明属性。从我所读到的关于EF Core的内容来看,这还不是一个选择。

配方参考工作完成后,对于InventoryItem,它将是相同的。

我在这篇文章中介绍了使用引用与FK(而不是两者)的内容: http://www.practicagility.com.au/2017/10/27/ef-a-1st-class-citizen-part-4-using-references-vs-keys/