Рассмотрим следующую простую таблицу пользователей
Я хочу написать Linq To SQL Code, который возвращает пользователя некоторым предикатом, например, адресом электронной почты, или создает пользователя, если он еще не существует. Код может выглядеть так:
User GetUser(String name, String email) {
using (var context = new DataContext()) {
User user = context.Users.FirstOrDefault(u => u.email.Equals(email));
if (user != null)
return user;
user = new User() { name = name, email = email };
context.Users.InsertOnSubmit(user);
context.SubmitChanges();
return user;
}
}
Код может выполняться параллельно, но не должен создавать дубликатов пользователей.
Я бы предпочел не создавать уникальное ограничение для таблицы по нескольким причинам. Вы видите какую-либо альтернативу, которая может быть реализована с использованием Linq To SQL и не касаясь базы данных?
Используйте TransactionScope
(по умолчанию уровень изоляции Serializable):
User GetUser(String name, String email)
{
using (var tran = new TransactionScope())
{
using (var context = new DataContext())
{
User user = context.Users.FirstOrDefault(u => u.email.Equals(email));
if (user != null)
return user;
user = new User() { name = name, email = email };
context.Users.InsertOnSubmit(user);
context.SubmitChanges();
tran.Complete();
return user;
}
}
}
Дополнительная информация о поддержке транзакций в LINQ to Sql: http://msdn.microsoft.com/en-us/library/bb386995