繁体   English   中英

在实体框架中将外键值设置回Null

[英]Setting a Foreign Key Value Back to Null in Entity Framework

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

例如,我有一个主键BatchDetailID = 10的现有BatchDetail记录,并且它与一个主键RunDetailID = 20,外键BatchDetailID = 10的现有RunDetail记录关联。我想取消关联RunDetail通过将RunDetails.BatchDetailID设置为null可以从BatchDetail中获取。

这是错误消息:

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

这是我的班级定义:

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:

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();
        }
    }
}

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

谁能看到我的缺点?

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

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

通过创建不Include("RunDetails")的新方法,可以解决此问题:

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

我按如下所示插入了1 BatchDetail和1 RunDetail。

using (var db = new AppContext())
{
    db.BatchDetails.Add(new BatchDetail { Id = 1 });
    db.RunDetails.Add(new RunDetail { Id = 1, BatchDetailId = 1 });
    db.SaveChanges();
}

然后,这里是引发相同错误的结果。

using (var db = new AppContext())
{
    // This is okay.
    var x = new RunDetail { Id = 1, BatchDetailId = 1, BatchDetail = new BatchDetail { Id = 1 } };
    db.RunDetails.Attach(x);
}
using (var db = new AppContext())
{
    // This is okay.
    var x = new RunDetail { Id = 1, BatchDetailId = null, BatchDetail = null };
    db.RunDetails.Attach(x);
}
using (var db = new AppContext())
{
    // This is okay.
    var x = new RunDetail { Id = 1, BatchDetailId = 1, BatchDetail = null };
    db.RunDetails.Attach(x);
}
using (var db = new AppContext())
{
    // A referential integrity constraint violation occurred: The property 
    // value(s) of 'BatchDetail.Id' on one end of a relationship do not match the property 
    // value(s) of 'RunDetail.BatchDetailId' on the other end.
    var x = new RunDetail { Id = 1, BatchDetailId = null, BatchDetail = new BatchDetail { Id = 1 } };
    db.RunDetails.Attach(x);
}

您的情况应该相同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM