LINQ to SQL更新(“无法添加一个已经在使用的密钥的实体.linq to sql”问题) [英] LINQ to SQL update ("cannot add an entity with a key that is already in use. linq to sql" problem)

查看:87
本文介绍了LINQ to SQL更新(“无法添加一个已经在使用的密钥的实体.linq to sql”问题)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难使用LINQ To SQL将实体更新到我的数据库。



我正在使用Windsor Castle为我的存储库工作的MVC网站。我正在使用Sanderson的Pro ASP.NET MVC框架作为指南使用VS 2010.



我的问题在于我的存储库中的以下代码:



  public   void 保存(评论评论)
{
if (comment.CommentID == 0
{
m_commentsTable.InsertOnSubmit(comment);
}
else if (m_commentsTable.GetOriginalEntityState(comment)== null
{
m_commentsTable.Attach(comment);
m_commentsTable.Context.Refresh(RefreshMode.KeepCurrentValues,comment);
}

m_commentsTable.Context.SubmitChanges();
}





代码是图书示例的直接副本(工作正常)但已修改为我的实体(评论)。 m_commentsTable的类型为Table< Comment>



调用此方法是为了保存新的Comment对象以及更新现有的对象。保存新对象工作正常,但是在调用Attach时更新现有对象失败并出现以下错误:



无法添加具有已存在的密钥的实体使用。



我用Google搜索了问题,发现很多人遇到类似的问题。我尝试了很多解决方案,但没有工作。



我试过:



- 从中​​获取原始对象表并将旧对象和新对象传递给Attach:例如附上(评论,原始评论)。我得到了同样的错误。



- 将'true'作为第二个arg传递给Attach。我收到以下错误:如果实体声明版本成员或没有更新检查策略,则只能在没有原始状态的情况下附加实体。



- 将Comment的列上的UpdateCheck属性更改为Never后,将'true'作为第二个arg传递给Attach。我得到了原始错误。



一些论坛帖子建议我创建另一个DataContext并将我的新对象附加到它。这似乎很浪费。此外,这还需要保存我的连接字符串(构造函数arg)。所有这些似乎有点混乱和不必要。



另一个建议是在我的表中添加一个版本列。这看起来也很浪费和尴尬。这让我很不舒服地在表格中添加一列来解决数据访问问题。



我有什么遗漏的东西吗?有没有人有另一个建议,我没有尝试过?



我仍​​然对为什么这些书的例子工作正常而感到困惑,但我的'副本'却没有。我有一种感觉,我错过了一些微妙的东西,但不知道它是什么。



我应该放弃LINQ To SQL并尝试其他方法吗?如果是这样,那可能是什么?



我是否应该克服我的不适并实施其他建议(另一个DataContext或额外标签栏)?





谢谢

解决方案

如果你正在使用EF,你需要做的就是编辑现有对象是获取它,更改属性,并在数据库对象上调用SaveChanges。您是否尝试过删除其他代码并使用更改后的对象进行保存?


我对这个问题的回答有点迟,但我只是我自己遇到了这个问题,似乎找到了解决方案。我会根据你的代码来说明这一点,这是有意义的。 

我正在做的是创建一个新的Comment对象,手动填写字段以重新创建现有记录,然后提交它以进行保存。这给了我错误。

我将其更改为加载现有注释,编辑我需要更改的字段,然后提交要保存的字段。工作得很完美。

因此根据您使用的图书,代码如下:

评论评论= CommentsRepository.Where(x => x.CommentID = thisID) 。第一();
comment.FieldToChange =新数据;
CommentsRepository.SaveRecord(comment);

GetOriginalEntityState假设副本是一个新记录 - 我想它没有基于身份字段进行比较,我认为它会。所以它之间存在冲突,因为它认为有2个记录具有相同的ID。

希望这有助于某人。< b > < / b >


I am having great difficulty updating an entity to my database using LINQ To SQL.

I am working on an MVC web site using Windsor Castle for my repositories. I am working with VS 2010 using the "Pro ASP.NET MVC Framework" book by Sanderson as a guide.

My problem is with the following code in my repository:

public void Save(Comment comment)
{
   if (comment.CommentID == 0)
   {
      m_commentsTable.InsertOnSubmit(comment);
   }
   else if (m_commentsTable.GetOriginalEntityState(comment) == null)
   {
      m_commentsTable.Attach(comment);
      m_commentsTable.Context.Refresh(RefreshMode.KeepCurrentValues, comment);
   }

   m_commentsTable.Context.SubmitChanges();
}



The code is a direct copy of the book examples (which work correctly) but modified for my entity (Comment). m_commentsTable is of type Table<Comment>

This method is called for saving new Comment objects as well as updating existing ones. Saving new objects works fine, but updating existing objects fails when calling Attach with the following error:

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

I Googled the issue and found a lot of people with a similar problem. I tried many solutions, but none work.

I tried:

- get the original object from the table and pass both old and new objects to Attach : e.g. Attach(comment, originalComment). I get the same error.

- pass 'true' as second arg to Attach. I get the following error: "An entity can only be attached as modified without original state if it declares a version member or does not have an update check policy."

- pass 'true' as second arg to Attach after changing the UpdateCheck attribute on Comment's columns to Never. I get the original error.

Some forum posts suggested that I create another DataContext and attach my new object to it. This seems wasteful. Also, this would also entail saving my connection string (constructor arg). All that seems a bit messy and unnecessary.

Another suggestion was to add a version column to my table. This also seems wasteful and awkward. It makes me uncomfortable adding a column to a table to work around a data access problem.

Is there something I am missing? Does anyone have another suggestion that I haven't tried?

I am still mystified as to why the book examples work fine, but my 'copy' does not. I have a feeling I am missing something subtle, but have no idea what it is.

Should I give up on LINQ To SQL and try another approach? If so, what might that be?

Should I get over my discomfort and implement one of other suggestions (another DataContext or extra label column)?


Thanks

解决方案

If you're using EF, all you need to do to edit an existing object is get it, change the properties, and call SaveChanges on your DB object. Have you tried just removing that other code and doing a save with the changed object ?


I'm a little late responding to this question, but I just ran into this problem myself and seem to have found the solution.  I'll put this in terms of your code so it makes sense.

What I was doing was creating a new Comment object, filling in the fields manually to recreate an existing record, and then submitting it to be saved.  That was giving me the error.

I changed that to load the existing Comment, edit the field I needed to change, and then submitted that to be saved instead.  Worked perfectly.

So based on the book you're using, the code would be something like:

Comment comment = CommentsRepository.Where(x => x.CommentID = thisID).First();
comment.FieldToChange = "New Data";
CommentsRepository.SaveRecord(comment);

GetOriginalEntityState assumed the copy was a new record - I guess it didn't compare it based on the identity field, which I thought it would.  So then it conflicted because it thought there were 2 records with the same ID.

Hope this helps someone.<b></b>


这篇关于LINQ to SQL更新(“无法添加一个已经在使用的密钥的实体.linq to sql”问题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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