C# 实体框架6带外键约束的多个savechanges事务

C# 实体框架6带外键约束的多个savechanges事务,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我在控制器中有以下代码。我试图批量更新数据库,但收到错误消息: INSERT语句与外键约束冲突 using (var context = new EFDbContext()) { using (var dbContextTransaction = context.Database.BeginTransaction()) { try { // MessageThread context.MessageT

我在控制器中有以下代码。我试图批量更新数据库,但收到错误消息:

INSERT语句与外键约束冲突

using (var context = new EFDbContext())
{
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {
        try
        {
            // MessageThread
            context.MessageThreads.Add(messageThread);
            context.SaveChanges();                            

            // Message
            context.Messages.Add(message);
            context.SaveChanges();

            // Recipient
            context.Recipients.Add(recipient);
            context.SaveChanges();

            dbContextTransaction.Commit();
        }   
        catch //(Exception ex)
        {
            ModelState.AddModelError("", "Something went wrong. Please try again.");

            return View("Message", model);

            // dbContextTransaction.Rollback(); no need to call this manually.
        }
    }   
}
消息类具有以下属性:

[ForeignKey("MessageThread")]
public long MessageThreadID { get; set; } // ID
public virtual MessageThread MessageThread { get; set; }
我无法添加消息,因为MessageThreadID MessageThread上存在外键约束。但我不能一次保存一个,这需要在一个事务中完成,以保证数据的完整性


我如何一次完成这项工作?也许我可以暂时禁用外键约束?

您的对象消息的属性中是否包含messageThread对象?也许你可以插入你的对象消息,谁包含你的对象消息线程

诸如此类:

using (var context = new EFDbContext())
{
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {
        try
        {
            message.MessageThread = messageThread;

            // Message
            context.Messages.Add(message);
            context.SaveChanges();

            // Recipient
            context.Recipients.Add(recipient);
            context.SaveChanges();

            dbContextTransaction.Commit();
        }   
        catch //(Exception ex)
        {
            ModelState.AddModelError("", "Something went wrong. Please try again.");

            return View("Message", model);

            // dbContextTransaction.Rollback(); no need to call this manually.
        }
    }   
}

这似乎是
Messge
MessageThread
之间的1:n关系
因此,例如,您应该在
Message
上有一个
MessageThread
的集合

public virtual List<MessageThread> MessageThreads {get;set;}
public虚拟列表MessageThreads{get;set;}
如果要在同一事务中将
消息线程
添加到
消息
,则应将其添加到该列表中

如果自动更改跟踪处于活动状态(默认情况下),EntityFramework会自动注意到某个实体已添加到
消息中,并将其置于当前上下文中。

因此,当您调用
SaveChanges
时,两者都应该保存在一个事务中。

我正在创建要保存在事务范围之外的对象。因此,我在事务块之前创建了一行三个对象。像这样:

MessageThread messageThread = new MessageThread();
Message message = new Message
{
    Subject = model.Subject,
    MessageText = model.MessageText,
    DateSent = DateTime.UtcNow,
    SenderID = sender.Id,
    MessageThreadID = messageThread.MessageThreadID
};
etc.
难怪它不起作用。我是个白痴。这是一个重构错误。这项工作:

using (var context = new EFDbContext())
{
    using (var dbContextTransaction = context.Database.BeginTransaction())
    {
        try
        {
            // MessageThread
            MessageThread messageThread = new MessageThread();
            context.MessageThreads.Add(messageThread);
            context.SaveChanges();

            // Message
            Message message = new Message
            {
                Subject = model.Subject,
                MessageText = model.MessageText,
                DateSent = DateTime.UtcNow,
                SenderID = sender.Id,
                MessageThreadID = messageThread.MessageThreadID
            };
            context.Messages.Add(message);
            context.SaveChanges();

            etc.

那不行。无论如何,我需要一个通用的解决方案,因为收件人的一个属性,即MessageID,与Message具有FK关系,就像Message中的MessageThreadID与MessageThread具有FK关系一样。这需要一批完成。