LINQ to SQL: чтение сущности при вызове "SubmitChanges" вызывает исключение DuplicateKeyException
Я испытываю странное поведение, которое я действительно не знаю, как обойти это. Я пытаюсь прочитать сущность сразу после того, как она была вставлена (сразу после ExecuteDynamicInsert) и когда возвращается частичный метод, я всегда получаю System.Data.Linq.DuplicateKeyException "База данных сгенерировала ключ, который уже используется. ".
Вот что я пытаюсь достичь с помощью очень простого примера:
Файл DataContext MyDataContext.cs:
public partial class MyDataContext
{
public override void SubmitChanges(System.Data.Linq.ConflictMode failureMode)
{
//using (TransactionScope ts = new TransactionScope())
//{
base.SubmitChanges(failureMode);
//}
}
partial void InsertCountry(Country instance)
{
this.ExecuteDynamicInsert(instance);
Country country = this.Countries.Where(c => c.CountryID == instance.CountryID).Single();
} //Exception occurs when this method returns...
}
Программный файл Program.cs:
class Program
{
static void Main(string[] args)
{
using (MyDataContext dataContext = new MyDataContext())
{
Country c = new Country()
{
Code = "C",
CreatedBy = "Me",
CreatedDate = DateTime.Now,
ModifiedBy = "Me",
ModifiedDate = DateTime.Now
};
dataContext.Countries.InsertOnSubmit(c);
dataContext.SubmitChanges();
}
}
}
Если я не читаю страну после того, как она была вставлена, код работает нормально, но мне нужно прочитать ее по любой причине, и я не хочу использовать набор изменений.
Есть ли способ достичь этого или обойти это поведение?
Заранее спасибо.
4 ответа
У меня было что-то подобное раньше. Попробуйте удалить сущность Country из конструктора DataContext и повторно добавить ее.
У меня было то же исключение. В моем случае я использовал instance.ExecuteDynamicUpdate вместо ExecuteDynamicInsert, но я не думаю, что это имеет значение.
Кажется, что важно то, что если вы вносите изменения в объект в иерархии объектов в пределах вставки / обновления, вы создаете эту ошибку. Мне кажется, это больше связано с оптимистичным параллелизмом, чем с дублирующимися ключами, но я не работаю в Microsoft...
Я решил свою проблему, создав новый метод в моем базовом бизнес-объекте, который вызвал SubmitChanges в контексте данных объекта, а затем внес все необходимые изменения.
В вашем случае вы можете попробовать добавить метод с именем Commit к вашему объекту Country следующим образом:
public sub Commit(dc as MyDataContext)
dc.SubmitChanges()
Dim country as Country = dc.Countries.Where(function (c) c.CountryID = Me.CountryID).Single()
end sub
Затем вызовите c.Commit вместо datacontext.SubmitChanges в Main.
Когда вы переопределяете поведение по умолчанию с помощью ExecuteDynamic [Insert | Update | Delete], вы не должны вызывать SubmitChanges. ExecuteDynamic [...] реализует изменение, непосредственно внешнее для DataContext. Вы получаете исключение, потому что вы пытаетесь применить изменения снова, когда вы вызываете SubmitChanges.
У меня была похожая проблема. В моем случае я переопределил INSERT по умолчанию с помощью хранимой процедуры, но забыл установить первичный ключ. Таким образом, всякий раз, когда я вставляю объекты, я получаю ошибку дублирующего ключа, так как все они возвращаются с первичным ключом, равным нулю.