实体框架6使用外键约束多次保存更改事务

时间:2016-02-02 06:56:04

标签: c# asp.net-mvc entity-framework

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

INSERT语句与FOREIGN KEY约束冲突。

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.
        }
    }   
}

Message类具有以下属性:

[ForeignKey("MessageThread")]
public long MessageThreadID { get; set; } // ID
public virtual MessageThread MessageThread { get; set; }

我无法添加消息,因为MessageThreadID在MessageThread上存在外键约束。但我不能一次保存一个,这需要在一次交易中完成数据完整性。

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

3 个答案:

答案 0 :(得分:0)

您的对象消息是否在其属性中包含messageThread对象?也许你可以插入你的对象Message,它包含你的对象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.
        }
    }   
}

答案 1 :(得分:0)

这似乎是MessgeMessageThread的1:n关系 因此,您应该在MessageThread上拥有Message的集合,例如

public virtual List<MessageThread> MessageThreads {get;set;}

如果您想在同一个交易中向MessageThread添加Message,则应将其添加到该列表中。

如果您启用了自动更改跟踪(默认情况下),EntityFramework会自动注意到实体已添加到Message并将其置于当前上下文中。
因此,当您调用SaveChanges时,两者都应保存在一个事务中。

答案 2 :(得分:0)

我正在创建要在事务范围之外保存的对象。所以我在事务块之前连续创建了三个对象。像这样:

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.