【问题标题】:Cannot add an entity with a key that is already in use update operation无法使用已在使用更新操作的键添加实体
【发布时间】:2014-08-18 08:12:27
【问题描述】:

我正在创建使用 LINQ To SQL 对数据库执行所有操作的小型应用程序。

现在我在这里给出我的数据库结构的一小部分,请看一下。

所以更新语言细节我正在使用类似这样的数据上下文获取登录对象。

XVDataContext Context = new XVDataContext ();

var myQuery = from objLogIn in Context.GetTable<LogIn>() where objLogIn.Emp_Id == nEmpId select objLogIn;

在 nEmpId 中,我总是有一些价值。

所以实际上我从数据库中获取所需的记录并使用以下代码将其存储在 objUser 对象中,这并没有造成任何问题。

LogIn objUser = myQuery.First<LogIn>();

现在要更新 LanguageDetail 我正在执行以下代码,但是当我执行 SubmitChanges 行时它会引发异常。

这是我正在执行更新的代码。

LanguageDetail obj = new LanguageDetail();
foreach (string sLanguages in TextBoxLanguagesKnown.Text.Split('\n'))
{
       obj.Emp_Id = objUser.Emp_Id;
       obj.Language = sLanguages.Trim();
}
objUser.LanguageDetails[0] = obj;

Context.SubmitChanges();

我已经阅读了以下链接。

cannot add an entity with a key that is already in use

LINQ To SQL exception with Attach(): Cannot add an entity with a key that is alredy in use

Cannot add an entity with a key that is already in use (LINQ)

通过阅读上述链接,我发现我在 ID 字段中犯了一些错误,但我仍然无法解决。

请告诉我提出这个问题的明确理解以及我该如何解决这个问题。

编辑:

我只是想更新 LanguageDetail 表。

当我尝试使用以下代码添加新对象时,它仍然会引发异常。

objUser.LanguageDetail.Add(obj);

【问题讨论】:

    标签: c# linq-to-sql


    【解决方案1】:

    您可能希望使用以下代码为特定用户添加/删除语言。

    var languages = TextBoxLanguagesKnown.Text.Split('\n');
    
    // Removes deleted languages (first find all language details that are missing from the UI).
    var deletedLanguages = objUser.LanguageDetails.Where(ld => !languages
        .Any(l => ld.Language == l.Trim())).ToArray();
    foreach(var deletedLanguage in deletedLanguages)
    {
        objUser.LanguageDetails.Remove(deletedLanguage);
        Context.LanguageDetails.DeleteOnSubmit(deletedLanguage);
    }
    
    // Adds new languages (then adds new language details that are not found in the database).
    var newLanguages = languages.Where(l => !objUser.LanguageDetails
        .Any(ld => ld.Language == l.Trim())).ToArray();
    foreach (string newLanguage in newLanguages)
    {
        var languageDetail = new LanguageDetail
        {
            Emp_Id = objUser.Emp_Id,
            Language = newLanguage.Trim()
        };
        objUser.LanguageDetails.Add(languageDetail);
    }
    
    Context.SubmitChanges();
    

    【讨论】:

    • 当我尝试您的代码时,它会抛出“InvalidOperationException”原因:- EntitySet 在枚举期间被修改。在第一个 foreach 循环中
    • 它再次抛出异常“InvalidOperationException”原因:“尝试删除 LogIn 和 LanguageDetail 之间的关系。但是,关系的外键之一 LanguageDetail.Emp_Id 不能设置为 null。 "
    • @NiravKamani,添加Context.GetTable&lt;LanguageDetail&gt;().Remove(deletedLanguage);,将GetTable&lt;LanguageDetail&gt;更改为上下文中设置的语言详细信息
    • "Context.GetTable().Remove(deletedLanguage);"删除方法不可用。
    • 上下文中有LanguageDetails吗?我把GetTable&lt;LanguageDetail&gt;()改成了LanguageDetails
    【解决方案2】:

    据我了解,您希望更新数据库中的 LanguageDetail 实体。为此,您必须执行以下操作之一:

    1. 根据 id 检索原始 LanguageDetail 对象,并更新该对象,而不是创建新对象并将现有对象的 id 分配给它。
    2. 将新创建的对象附加到您的上下文中,而不是仅仅将它的引用提供给您的 LanguageDetails 集合。 您看到的异常发生是因为 linq to sql 的行为方式是将 obj 威胁为您要插入的新对象,因此它会尝试将其插入语言详细信息表中。

    像这样修改你的代码应该可以工作:

    Context.LanguageDetails.Attach(obj);
    objUser.Employee_LanguageDetails[0] = obj;
    

    【讨论】:

    • 我认为您的解决方案可能是正确的,但在我的代码中我遇到了同样的异常。忘记上面的代码,如果可能的话,给我一个简单的例子,如何使用你自己的代码更新 LanguageDetail 表。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-21
    相关资源
    最近更新 更多