【问题标题】:How to delete related fields using Entity Framework如何使用实体框架删除相关字段
【发布时间】:2017-03-10 15:48:51
【问题描述】:

我有一个这样的对象:

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

    public string ExternalNumber { get; set; }


    public virtual InternalProperties InProperties { get; set; }

    public virtual ICollection<AdditionalPrice> PriceHistory{ get; set; }
}

和 InternalProperties 类:

public class InternalProperties
{
    [Key]
    public int Id { get; set; }
    public string  Field1{get; set;}
}

还有价格历史:

public class AdditionalPrice
{
    [Key]
    public int Id { get; set; }
    public double? Price { get; set; }
}

我的上下文是这样的:

public class myContext : DbContext
{
        static myContext ()
        {
            Database.SetInitializer<myContext >(null);
        }

        public myContext ()
            : base("myCtx")
        {
        }

        public DbSet<MyObject> Objects{ get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
           modelBuilder.Entity<myObject>().HasOptional(m => m.InProperties );
           modelBuilder.Entity<myObject>().HasMany(m => m.PriceHistory);
        }

}

最后我想像这样删除 myObjects :

            using (var _sdb = new MyContext())
            {
                _sdb.Configuration.AutoDetectChangesEnabled = false;
                var myList = _sdb.Objects.Where(m => m.Id > 5).OrderBy(c => c.Id).ToList();
                foreach(var obj in myList)
                {
                 _sdb.Objects.Remove(obj)
                }

            }
_sdb.SaveChanges();

我在 SaveChanges() 遇到了这个异常:

{"保存不对外暴露的实体时出错 他们关系的关键属性。 EntityEntries 属性 将返回 null,因为无法将单个实体标识为 异常的来源。保存时的异常处理可以是 通过在实体类型中公开外键属性变得更容易。 有关详细信息,请参阅 InnerException。"}

Inner Exception 说:

{"DELETE 语句与 REFERENCE 约束冲突 \"FK_dbo.AdditionalPrice_dbo.MyObject_MyObject_Id\"。冲突 发生在数据库 \"myobject\"、表 \"dbo.AdditionalPrice\"、 列 'myObject_Id'。\r\n语句已终止。"}

这些异常很容易解释,但我不知道如何安全地删除这些对象。我很感激任何帮助。提前致谢。

【问题讨论】:

  • 信息清楚,有外键,要先删除外记录
  • @LeiYang 是的,我也明白了,但我不知道该怎么做。
  • @LeiYang 我无法访问并删除那个价格历史记录。

标签: c# entity-framework


【解决方案1】:

我认为你需要这样的东西:

var pricesToBeDeleted = _sdb.AdditionalPrices.Where(ap=>ap.MyObjectId == obj.Id);
_sdb.AdditionalPrices.Remove(pricesToBeDeleted);
_sdb.Objects.Remove(obj)

AdditionalPrices 的类型为 DbSet&lt;AdditionalPrice&gt;。您应该在 myContext 类中添加以下行:

public DbSet<AdditionalPrice> Objects{ get; set; }

关于AdditionalPrice 类,我看不到MyObject 的外键。我认为你在那里错过了一些东西。我的意思是你可能有类似以下的东西:

public class AdditionalPrice
{
    [Key]
    public int Id { get; set; }
    public double? Price { get; set; }
    public int MyObjectId { get; set; }
}

其中MyObjectId 是外键。如果名称 MyObjectId 与您应该更改的相应列名称不同,以便它们相互匹配。

【讨论】:

  • 如您所见,我的上下文没有 AdditionalPrices。我应该先将其添加到上下文中吗?
  • 是的,这是我几秒钟前写的:)
  • 感谢您的回答,但 AdditionalPrice 类没有外键。使用 Id 删除仍然安全吗?
  • @jason 欢迎您。如果我没记错的话,Id 是记录的主键,而不是 MyObject 表的外键。话虽如此,我认为这是不正确的。此外,由于您收到的错误消息指的是外键,而AdditionPrice 表示相应表的记录,我们不应该有像MyObjectId 这样的属性,它本来就是外键吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-04
  • 2019-04-14
  • 1970-01-01
相关资源
最近更新 更多