在实体框架中将外键值设置回Null [英] Setting a Foreign Key Value Back to Null in Entity Framework

查看:82
本文介绍了在实体框架中将外键值设置回Null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从记录中删除外键值时,我无法将记录保存到SQL Server数据库中。

I have been unable to save a record to a SQL Server database when removing a foreign key value from the record.

例如,我有一个现有的BatchDetail记录具有主键BatchDetailID =10。它与具有主键RunDetailID = 20和外键BatchDetailID = 10的现有RunDetail记录相关联。我想通过将RunDetails.BatchDetailID设置为来将RunDetail与BatchDetail取消关联

As an example, I have an existing BatchDetail record with a primary key BatchDetailID = 10. And it is associated with an existing RunDetail record that has a primary key RunDetailID = 20, and a foreign key BatchDetailID = 10. I want to disassociate the RunDetail from the BatchDetail by setting RunDetails.BatchDetailID to null.

这是错误消息:


参照完整性约束冲突发生:关系的一端 BatchDetail.BatchDetailID的属性值与另一端 RunDetail.BatchDetailID的属性值不匹配。

A referential integrity constraint violation occurred: The property value(s) of 'BatchDetail.BatchDetailID' on one end of a relationship do not match the property value(s) of 'RunDetail.BatchDetailID' on the other end.

这是我的课程定义:

public class RunDetail
{
    public int RunDetailID { get; set; }
    public Nullable<int> BatchDetailID { get; set; }

    public virtual BatchDetail BatchDetail { get; set; }
}

public class BatchDetail
{
    public int BatchDetailID { get; set; }

    public virtual ICollection<RunDetail> RunDetails { get; set; }
}

RunDetail 对象具有 BatchDetailID 值,我尝试将其设置回null:

The error occurs when a RunDetail object has a BatchDetailID value, and I try to set it back to null:

public class MyController : Controller
{
    private ISvr _myService;

    public ISvr MyService
    {
        get { return _myService ?? (_myService = new MyHandler().GetMyService()); }

        set
        {
            _myService = value;
        }
    }

    public void UpdateBatch(int id)
    {
        foreach (var batchDetail in MyService.ReadBatchDetails(id))
        {
            var runDetail = MyService.ReadRunDetail(batchDetail.RunDetailID);

            runDetail.BatchDetailID = null;
            runDetail.BatchDetail = null; // I have tried with, and without, this line

            MyService.UpdateRun(runDetail );
        }
    }
}

public class MyHandler
{
    public ISvr GetMyService()
    {
        return new MySvr();
    }
}

[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall)]
public class MySvr : IMySvr
{
    public void UpdateRun(RunDetail runDetail)
    {
        using (var myEntities = new MyEntities())
        {
            myEntities.RunDetails.Attach(runDetail); // This is where the exception hits
            myEntities.Entry(runDetail).State = EntityState.Modified;
            myEntities.SaveChanges();
        }
    }
}

所有其他记录更新,包括将外键值更改为另一个,可以正常工作。

All other record updates, including changing the foreign key value to another, work correctly.

有人可以看到我的缺点吗?

Can anyone see what my flaw is?

推荐答案

问题植根于我未在问题中包含的方法。当我检索父 BatchDetail 记录时,我包括了 RunDetails记录:

The problem was rooted in a method that I did not include in my question. When I retrieved the parent BatchDetail record, I included the "RunDetails" records:

public List<BatchDetail> ReadBatchDetails(int id)
{
    using (var myEntities = new MyEntities())
    {
        return myEntities.BatchDetails
            .Include("RunDetails") // This is the problem
            .AsNoTracking().ToList();
    }
}

通过创建不<$ c的新方法$ c> Include( RunDetails),问题已解决:

By creating a new method that does not Include("RunDetails"), the problem is resolved:

public List<BatchDetail> ReadBatchDetailsWithoutRunDetails(int id)
{
    using (var myEntities = new MyEntities())
    {
        return myEntities.BatchDetails.AsNoTracking().ToList();
    }
}

这篇关于在实体框架中将外键值设置回Null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆