У меня есть очень простой класс, созданный Entity Framework (V 6.2) со свойством, которое также является первичным ключом.
public class Product
{
public string Name { get; set; }
}
Как я могу убедиться, что когда я создаю новый элемент (или изменяю один из существующих), это не позволяет мне сделать это, если имя уже существует?
Я знаю, что MyContext.SaveChanges()
сгенерирует исключение, но можно ли сделать это раньше? Как при звонке в MyContext.Products.Add(MyNewProduct)
? Или когда имя изменено?
Я мог бы изменить свойство set в автоматически сгенерированном файле, созданном EF, но оно будет стираться каждый раз, когда я регенерирую модель ...
База данных @Wurd сначала, иначе ему не пришлось бы регенерировать модель
Просто имейте в виду, что если вы генерируете ключ в коде (не db auto int) и ваше приложение имеет много одновременных запросов, вы можете столкнуться с проблемами параллелизма. Например, запрос A => B => A получает ID => B получает ID => A Saved => B конфликт параллелизма с A при сохранении.
@Wurd Я использую подход Database First. Я не буду сталкиваться с проблемами параллелизма, так как эта программа предназначена для одновременного использования только на одном компьютере (я буду помнить об этом, если это изменится).
if (db.Products.Any(p => p.Name == newProduct.Name))
{
return "A record with the same name already exists.";
}
else
{
db.Products.Add(newProduct);
db.SaveChanges();
}
Я согласен, это ваш лучший вариант. Преимущество использования any заключается в том, что он возвращается сразу после того, как находит совпадение.
Прежде всего, я не думаю, что проверка уникальности в установщике или в методе context.Add () - хорошая идея, поскольку вы можете столкнуться с проблемами производительности при одновременном добавлении нескольких сущностей. Возможно, лучше добавить проверку в переопределенном методе SaveChanges ().
Вы можете изменить шаблон генерации кода EF (https://docs.microsoft.com/en-us/ef/ef6/modeling/designer/codegen/), чтобы генерировать проверки для каждого требуемого типа сущности на основе некоторого расширенная собственность или некоторых других метаданных в базе данных, примерно так:
public override int SaveChanges()
{
var productNames = ChangeTracker.Entries<Products>()
.Where(x => (x.State == EntityState.Added) ||
(x.State == EntityState.Modified && x.OriginalValues["Name"] != x.CurrentValues["Name"]))
.Select(x => x.Entity.Name)
.ToList();
if (Products.Any(x => productNames.Contains(x.Name)))
{
throw new Exception("Duplicated keys");
}
// same goes for other similar entities
return base.SaveChanges();
}
Я проверил вашу ссылку, но они, видимо, пытаются отговорить от изменения шаблонов. Спасибо, в любом случае
Я не думаю, что они препятствуют изменению шаблонов в целом. Насколько я понимаю, они просто рекомендуют использовать одни шаблоны в качестве основы для изменений по сравнению с другими.
Используете ли вы подход CodeFirst или DatabaseFirst?