Я согласен с @Ladislav - Method_1 - плохой подход.Позвольте базе данных вызывать исключения, которые перехватываются EF - не пытайтесь проглотить эти исключения самостоятельно.
Вы на правильном пути, используя метод 1.
Вот как я это делаю - каку меня также есть отдельный контекст (POCO, отслеживание изменений отсутствует, ASP.NET MVC).
Интерфейс BLL: (обратите внимание, у меня есть TPT в моей модели, следовательно, дженерики. "Post" является абстрактным)
void Add(Post post);
void Update<TPost>(TPost post) where TPost : Post, new();
Ограничение new()
имеет решающее значение - вскоре вы поймете, почему.
Я не покажу, как я делаю "Добавить", потому что это просто, как вы думаете - AddObject(entity);
«Обновление» - сложная часть:
public class GenericRepository<T> : IRepository<T> where T : class
{
public void Update<T2>(T2 entity) where T2: class, new()
{
var stub = new T2(); // create stub, now you see why we need new() constraint
object entityKey = null;
// ..snip code to get entity key via attribute on all domain entities
// once we have key, set on stub.
// check if entity is already attached..
ObjectStateEntry entry;
bool attach;
if (CurrentContext.ObjectStateManager.TryGetObjectStateEntry(CurrentContext.CreateEntityKey(CurrentContext.GetEntityName<T>(), stub), out entry))
{
// Re-attach if necessary.
attach = entry.State == EntityState.Detached;
}
else
{
// Attach for first time.
attach = true;
}
if (attach)
CurrentEntitySet.Attach(stub as T);
// Update Model. (override stub values attached to graph)
CurrentContext.ApplyCurrentValues(CurrentContext.GetEntityName<T>(), entity);
}
}
И это работает для меня.
Что касается ключа сущности, я использовал атрибуты в своих классах домена.Альтернатива (к которой я собираюсь перейти) состоит в том, чтобы все сущности моего домена реализовали интерфейс, который указывает, что все сущности домена должны иметь свойство, называемое EntityKey.Тогда я буду использовать этот интерфейс в моих ограничениях.По сути, мне нужен был динамический способ создания объектов-заглушек в общем хранилище.
Мне лично не нравится идея " проверки идентификатора, если его> 0, то это обновление ».Поскольку я работаю с ASP.NET MVC, если я (или другой разработчик) забудет привязать идентификатор к представлению, он не будет пропущен, поэтому даже если это может быть обновление, потому что идентификатор == 0это будет добавлено.
Я хотел бы быть явным об операциях.Таким образом, я могу выполнить Добавить / Обновить отдельную логику проверки.