Comments 17
Эммм… Транзакции?
(В сторону: ну и гадость же этот ваш EF)
(В сторону: ну и гадость же этот ваш EF)
0
не совсем транзакции. но согласен, слегка похоже!
0
Вы вопрос не поняли.
0
Как уже отметили, вы не поняли вопроса. Где и как у вас организуются транзакции?
0
И unitRepository и cityRepository имеют внутри себя каждый свой экземпляр DBContainer. При вызове BaseRepository.SaveChanges() каждого из них, по порядку, будет: открыто свое соединение -> начата транзакция -> выполнены CRUD команды SQL -> комит/ролбек -> закрытие соединения.
В итоге: получаем отдельные «транзакции» отдельно для каждого объекта типа BaseRepository, или так: в результате можем иметь сохраненные изменения unitRepository и «обломавшийся» cityRepository.SaveChanges().
Не уверен, поможет ли выполнение обоих SaveChanges() внутри using (TransactionScope ts = new TransactionScope()) {...}.
Или я неправильно понял вопрос.
В итоге: получаем отдельные «транзакции» отдельно для каждого объекта типа BaseRepository, или так: в результате можем иметь сохраненные изменения unitRepository и «обломавшийся» cityRepository.SaveChanges().
Не уверен, поможет ли выполнение обоих SaveChanges() внутри using (TransactionScope ts = new TransactionScope()) {...}.
Или я неправильно понял вопрос.
0
Да, правильно поняли. Что неправильно — так это подобное поведение. А использование TransactionScope вполне себе может эскалировать транзакцию до распределенной.
0
How to run two Entity Framework Contexts inside TransactionScope without MSDTC?
Что неправильно — так это подобное поведение. — Мне кажется что все дискусии решаютя бизнес-задачами. Если именно_такое нужно для конткретного_проекта и требований — велком! Ну и да, нужно понимать какие ограничения возможны в применении данного подхода.
Что неправильно — так это подобное поведение. — Мне кажется что все дискусии решаютя бизнес-задачами. Если именно_такое нужно для конткретного_проекта и требований — велком! Ну и да, нужно понимать какие ограничения возможны в применении данного подхода.
0
А чем именно неправильно подобное поведение? Эскалацию до распределенной можно побороть через ручное управление Enlistment-ом. Будет гарантированно одно соединение в пределах TransactionScope (и одна SqlTransaction), расшаренное для всех контекстов.
0
Потому что вообще говоря транзакции — дело клиентского по отношению к DAL/репозиторию/следующему-баззвордному-паттерну кода.
0
Эммм… Транзакции?
вообще говоря транзакции — дело клиентского по отношению к DAL/репозиторию/следующему-баззвордному-паттерну кода.
Я тоже не понял вопроса. И вашего же ответа.
DAL должен поддерживать транзакции, а не организовывать их. Репозиторий [в дописанном до совместимости с TransactionScope варианте, гарантированно не делающий эскалацию внутри] будет поддерживать и Explicit и Implicit транзакции. Если автор решил не реализовать поддержку транзакций в рамках статью — это его выбор. Это же статья, а не дамп кода живого проекта с комментариями.
0
Производительность на нескольких процессорах с ГГц-ами — конечно не главное, но… Рефлексия на каждый чих достаточно жестокая вещь.
А потом я не понял особой разницы между new BaseRepository().AllItems и new DBContainer().UnitSet. Конструкции по моему равнозначные (без полиморфизма же). По длине и по сложности очень похожие.
А потом я не понял особой разницы между new BaseRepository().AllItems и new DBContainer().UnitSet. Конструкции по моему равнозначные (без полиморфизма же). По длине и по сложности очень похожие.
+2
Да, производительность возможно несколько пострадает. Но по моему скромному мнение удобство повышается…
Разницы особой и нету. Только BaseRepository не требует явного задания названия контейнера, вот и всё.
Разницы особой и нету. Только BaseRepository не требует явного задания названия контейнера, вот и всё.
0
Производительность — однозначна спорная вещь, я на ней не настаиваю. К тому же при выполнении sql-запросов. Просто замечание. Факт просадки может определить только профайлер.
А вот с интерфейсами — выигрыш по моему спорен. У вас упоминание о типе объектов просто переехало в другое место.
А вот с интерфейсами — выигрыш по моему спорен. У вас упоминание о типе объектов просто переехало в другое место.
0
Рефлексию можно заменить на компилируемые лямбды. Работать будет… быстрее. И выглядеть — намного круче.
+1
1. Посмотрите еще на один очень интересный проект расширения возможностей Entity Framework 1.0/4.0:
ADO.NET Entity Framework Extensions. Лично я уже даже не представляю себе проект на EF без использования функционала этих «расширений».
2. А для получения сущности по ключу я использую метод-расширение в классе DBContainer:
ADO.NET Entity Framework Extensions. Лично я уже даже не представляю себе проект на EF без использования функционала этих «расширений».
2. А для получения сущности по ключу я использую метод-расширение в классе DBContainer:
public T GetObjectByKey(object id) where T : EntityObject
{
string entitySetName = this.MetadataWorkspace.GetEntityContainer(this.DefaultContainerName, DataSpace.CSpace)
.BaseEntitySets.Where(bes => bes.ElementType.Name == typeof(T).Name)
.FirstOrDefault().Name;
string entitySetKeyName = string.Format("{0}.{1}", this.DefaultContainerName, entitySetName);
EntityKey key = new EntityKey(entitySetKeyName, "ID", id);
return (T)this.GetObjectByKey(key);
}
3. Получается, что у Вас unitRepository и cityRepository каждый имеет СВОИ/РАЗЛИЧНЫЕ экземпляры DBContainer(). Это, конечно, вариант и все зависит от требований конкретной задачи, но я бы еще добавил бы в конструктор BaseRepository параметра типа DBContainer: вдруг понадобится работать с уже ранее созданным экземпляром DBContainer. Имхо.
+1
Хорошая попытка, но попробуите почитать на эту тему побольше. Если нет проблем с англииским, то можете начать с этои статьи: huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/ где подробно изложена схема создания репозитория. Там используется замечательныи метод ObjectContext.CreateObjectSet<TEntity>() вместо рефлексии.
+2
Sign up to leave a comment.
Универсальный репозиторий ADO.NET Entity