Как стать автором
Обновить

Комментарии 72

Хороший обзор.
Сам единственно заменил бы Ninject на Autofac.
И, возможно, добавил KnockoutJS.
спасибо!
KnockoutJS входит в состав ASP.NET MVC 4 Beta
А если сравнивать с Unity, что лучше?
Ничего, они «все одинаковые» в этом плане. То есть, все способны делать все, что полагается современному контейнеру.
Если говорить о наборе возможностей, то как уже сказали, современные контейнеры обладают примерно одинаковым набором возможностей. Это раньше были только PicoContainer да StructureMap, а сейчас контейнеров много.
Unity в первых версиях отличался очень громоздким синтаксисом, как сейчас — не знаю.
Autofac всегда старался избегать Reflection'а, одним из первых стал использовать такие фичи C#, как Generics, lambda expressions, что и сделало его одним из самых быстрых контейнеров. Есть интеграция с WCF, ASP.NET, ASP.NET MVC, NMock, DynamicProxy, Moq.
Хорошая документация и подробные статьи по различным аспектам использования в блоге автора.
Часто обновляется, автор работает в Microsoft над проектом MEF.
Сам юзаю StructureMap и AutoFac, но Ninject — вполне достоен. Тут уже дело вкуса.
Это уже сугубо личные предпочтения.
Я бы использовал Castle.Windsor для контейнеров =) Так уж сложилось исторически
Да, согласен, чаще всего это вопрос личных предпочтений. Мне Autofac нравится, помимо прочего, лаконичным синтаксисом, но это дело вкуса.

Не раз встречал сравнения производительности, где Ninject не блистал. Вот например:
philipm.at/2011/0808/
Статья прошлогодняя, возможно у Ninject'f что-то успело поменяться к лучшему в плане производительности.
Ага, судя по данной статье, Ninjet и Unity вообще черепахи по сравнению с Autofac.
Немного истории: Глен Блок, автор замечательной библиотеки контейнеров MEF ушел работать в команду WCF, где начал делать упрощенный REST API в рамках WCF, эта работа получила название WCF Web API. Потребность в упрощенном способе создания сервисов поверх HTTP была давно.

Набор получился настолько хорошим, что его решили включить в саму базовую систему ASP.NET. Это включение и получило название ASP.NET WebAPI. Таким образом WebAPI — это часть ASP.NET, базовый компонент. Поэтому, например, WebAPI можно использовать в проектах ASP.NET WebForms.
спасибо!
Хочется обратить внимание на то, что уже вышел Entity Framework 4.3. В нем появилось пару приятных плюшек, миграции, например.
Миграция была ещё и в 4.1, только срая и качалась отдельно, из возможностей было только генерация SQL скрипта для внесения изменений в базу.
У Entity Framework есть один существенный минус, который для кого-то перекрывает все плюсы — он не поддерживается в Mono, во всяком случае пока.
Ну и соответственно другие от него зависимые packages также имеют такой минус.

А так — спасибо за подбор, буду иметь ввиду. Правда хотелось бы еще и исходников для не слишком продвинутых и ленивых людей вроде меня.
После Scaffold на Product и Category и переходу на представление создания продукта получаем ошибку:

«Value cannot be null. Parameter name: source» на строке:

@Html.DropDownListFor(model => model.CategoryId, ((IEnumerable<MvcPackTest.Models.Category>)ViewBag.PossibleCategories).Select(option => new SelectListItem {
        Text = (option == null ? "None" : option.Name), 
        Value = option.CategoryId.ToString(),
        Selected = (Model != null) && (option.CategoryId == Model.CategoryId)
    }), "Choose...")


:(
В контроллере имеем:

        public ActionResult Create()
        {
	    ViewBag.PossibleCategory = ...;
            return View();
        } 


а в представлении:

@Html.DropDownListFor(...ViewBag.PossibleCategories).Select(...


Печально.
честно говоря, у меня все работает.
как вариант, попробуйте сначала заполнить хотя бы категории.

однако возможен и баг )
Я уже написал выше что для контроллера свойство ViewBag генерируется в ед. числе, а для представления по мн… У вас это не так?
все понял — я подумал, что не происходит запросов, и данные = null.
насчет ед. и мн. числа — да это самый настоящий баг. почему так происходит? не знаю. смотрел исходники T4-шаблонов, но везде используется плюрализация имен.
возможно баг скрыт где в недрах T4-скаффолдера.
как решение, Ctrl+H :)
С WebAPI, конечно, приехали наконец. Мы уже 3 года как написали свой неизменный ActionInvoker, который позволяет возвращать из контроллера модель вместо ActionResult — а это самое ценное свойство ApiController'а. Конечно, всякие вкусности, вроде «IQueryable через адресную строку» надо будет еще распробовать.
blog.ploeh.dk/2012/03/26/IQueryableIsTightCoupling.aspx IQueryable очень нехорошо выставлять наружу. SQL сгенерированный по произвольным запросам содержит обычно такое количество join и другого непотребства что самое крутое железо уходит на секунды.
"
То сейчас необходимо лишь изменить метод GetAllProducts:

public IQueryable GetAllProducts(int category)
{
var products = from p in productRepository.All
where p.CategoryId == category
select p;
return products;
}
И в браузере, например, набрать следующее:
localhost/api/products?category=1&$orderby=Name
"

Ну да, конечно. Очередная серебряная пуля. Теперь задумываемся внимательно.

Любое соединение с БД — это… соединение. Оно может быть инкапсулировано в контекст, а может быть в него не инкапсулировано, но его надо и открыть, и закрыть. Смотрим в реализацию репозитория — и видим там, конечно же, этот самый контекст (ProductsContext context = new ProductsContext();), причем, «естественно», без детерминированного закрытия (что означает, что соединение будет закрыто тогда, когда этого захочется контексту, то есть, в худшем случае, тогда, когда до этого класса доберется GC). В контроллере, понятное дело, повтор того же сценария — репозиторий открывается при создании контроллера и не имеет явного закрытия.

И это, на самом деле, не от лени создателей, и не от того, что они не знают, как работать с IDisposable, а потому, что если реализовать в репозитории принудительное закрытие, то вся эта красота с «вернем из контроллера IQueryable, а потом сделаем с ним все операции» работать не то что бы перестанет, но по крайней мере не будет выполнять эти операции на уровне базы.

Что в сухом остатке? В сухом остатке — надо очень внимательно следить за тем, как ведут себя соединения в подобных (deferred execution) сценариях. Да, утверждается, что EF открывает соединения по месту и закрывает их сразу после завершения работы запроса. Окей, прекрасно. Главное, чтобы у вас за репозиторием оказался именно EF, который так умеет, и чтобы его понимание «завершения работы» совпало с вашим.
ИМХО ADO.NET уже настолько умен и прозрачен, что можно забыть про соединения.
По факту большая часть открытия новых соединений, это вызовы в контексте уже открытого соединения.
«ИМХО ADO.NET уже настолько умен и прозрачен, что можно забыть про соединения.»
Вообще-то, нет. Как нужно было аккуратное управление, так и нужно. Не далее как в прошлом году получили падение приложения из-за того, что программист забыл закрыть соединение в часто используемом запросе. *Два* тестировщика положили приложение.

«По факту большая часть открытия новых соединений, это вызовы в контексте уже открытого соединения.»
Вы путаете. Connection pool (а вы говорите о нем) экономит ресурсы на создание/уничтожение соединений, а не на их открытие/закрытие. Открытое соединение — это реально занятые ресурсы сервера БД, и их все стараются экономить, и держать соединение открытым как можно меньше.
Ты прав. Сам сталкивался с этим. Еще была проблема, что изменяешь данные, а так как Dispose не вызывается, то реально данные остались старые и в другом контексте они старые. Чтобы избежать открытых соединений, нужно интерфейс репозитория наследовать от IDisposable и организовать работу DI Container'ов таким образом, чтобы на каждый HttpContext создавался свой репозиторий, а в конце вызывался Dispose. Посмотреть как сделано с Unity, например, можно в расширении Unity.MVC.
«Еще была проблема, что изменяешь данные, а так как Dispose не вызывается, то реально данные остались старые и в другом контексте они старые.»
??! Вообще-то, вызов SaveChanges гарантирует, что данные ушли в БД. Вот тут-то Dispose не при чем.

«Чтобы избежать открытых соединений, нужно интерфейс репозитория наследовать от IDisposable и организовать работу DI Container'ов таким образом, чтобы на каждый HttpContext создавался свой репозиторий, а в конце вызывался Dispose.»
Скажем так, это _один_ из вариантов.

Я в основном предпочитаю детерминированное управление жизненным циклом, с явным using. Это намного очевиднее для разработчика, и работает (практически) во всех случаях — кроме вот такого вот deferred execution, как предлагает Web API.
Даже после SaveChanges данные не обновлялись. Проблема решилась сменой LifetimeManager'а на HierarchicalLifetimeManager и использовании Child DI Container'а для каждого HttpContext'а (суть Unity.MVC). При этом контейнер вместе с созданными объектами правильно Dispose'ился.

А явный using вызывается, например, в MembershipProvider'е, потому что он создается 1 на Application и там схема описанная выше не работает.
«Даже после SaveChanges данные не обновлялись.»
Это очень странно. Dispose отпускает ресурсы, а не коммитит изменения.

Я подозреваю, что ваша проблема была не в том, что контекст не отпускался, а в том, что вы брали контекст, который уже содержал данные, и они успевали устареть.
blog.ploeh.dk/2012/03/26/IQueryableIsTightCoupling.aspx
Проблемы не только с «висячим» контекстами. А также с неоптимальными запросами, в EF LINQ бывает достаточно поменять порядок чтобы запрос сократился в разы. По соображениям производительности нам сегодня нужно денормализировать некоторые таблицы, при подходе с IQueryable вы зацепите всех клиентов.

«По соображениям производительности нам сегодня нужно денормализировать некоторые таблицы, при подходе с IQueryable вы зацепите всех клиентов.»
Вот этот пассаж мне совершенно не очевиден. Хотя бы потому, что он оперирует разными уровнями абстракции: таблицы — это БД, а IQueryable в данном контексте — внешний публичный API, т.е. на три уровня абстракции дальше (запрос поверх БД, провайдер поверх запроса, API поверх провайдера).

А вообще, мы имеем дело с классической архитектурной дилеммой — гибкость, удобство и универсальность с одной стороны, и производительность — с другой. Ничего нового, в общем-то.
msdn.microsoft.com/en-us/library/system.linq.iqueryable.aspx
— Provider — это такая ох… тельно большая деталь реализации. Я то знаю что MySQL .NET Connector не имеет оператора IN и генерирует код похуже чем Майкрософтовский для MS SQL, но разкажите ли вы об этом все своим клиентам, и сколько из них решат не заморачиватся и положат сервер JOIN-ом на 16 таблиц?
— Expression — учитывает взаимоотношения, IEnumerable это более слабая связь.
— Из соображений производительности часть данных мы выносим в Dynamo DB, клиенты об этом ни слухом ни духом и это правильно.
В сухом остатке: Uncle Bob Martin определяет хорошую архитектуру, как такую которая позволяет откладывать принятие важных решений до момента когда это будет действительно нужно. Наш подход позволил сменить: MS SQL на MySQL, MySQL частично заменить Dynamo DB, на следующем этапе ещё часть иерархичных структур уедет в Ellastic Search и клиентов это до поры времени никак не затрагивает. Что было бы с IQueryable да тоже самое только потеряли время на отвязывание IQueryable.
«Provider — это такая ох… тельно большая деталь реализации.»
Я в курсе. Я их писал.

«Я то знаю что MySQL .NET Connector не имеет оператора IN и генерирует код похуже чем Майкрософтовский для MS SQL, но разкажите ли вы об этом все своим клиентам, и сколько из них решат не заморачиватся и положат сервер JOIN-ом на 16 таблиц?»
Простите, «мои клиенты» — это люди. И их никто не пустит писать join-ы в сервере.

«Наш подход позволил сменить [...] Что было бы с IQueryable да тоже самое только потеряли время на отвязывание IQueryable. „
Угу. А запросы произвольной сложности “ваш подход» тоже позволяет строить?

В общем, шило на мыло. Кому нужно чистую производительность — тем, понятное дело, и EF не к месту, и IQueryable не очень с руки. Но не всем она нужна, некоторым важнее другие, уже описанные выше аспекты.
Это хорошая лазейка для говнокодеров :).
Не имея знаний и опыта можно такого будет понаписать, что у многих потом волосы дыбом вставать будут.
Для тех кто понимает это довольно интересная возможность.

Естественно разработчики столь интересной возможности подумали над открытием и закрытием контекста.
Для работы с базой данных нужно пользоваться немного другим контроллером (производные от System.Web.Http.Data.DataController) и тогда все встает на свои места.

Возврат IQueryable без использования System.Web.Http.Data.DataController контроллеров подходит для не больших коллекций уже выбранных объектов, это нужно знать и учитывать при разработке.
«Это хорошая лазейка для говнокодеров :).»
Такие вещи называются «способ выстрелить себе в ногу». Чем их в системе меньше (как и любого недетерминированного поведения), тем лучше.

«Для работы с базой данных нужно пользоваться немного другим контроллером (производные от System.Web.Http.Data.DataController) и тогда все встает на свои места.»
Ага. И убить тем самым всю идею паттерна Repository, описанного в статье. Нет, я не против, но только уж либо одно, либо другое.
Web Api на стадии беты и к пререлизу может многое измениться.
Сейчас можно написать свой класс производный от DataController для управления контекстом базы данных (например connection scope) и пользоваться своими репозиториями как и раньше
Вот только в посте об этом — ни слова. Зато рассказывают про ApiController.
DataController наследуется от ApiController и реализует IDisposable.

Если его не использовать, то можно обойтись следующим: для управления жизненнным циклом DbContext, можно реализовать IDisposable в самом репозитории, а в RepoModule прописать:

Bind().To().InRequestScope;

Ninject проконтролирует, чтобы в конце запроса был вызван Dispose().
Угу, спасибо.

Я, собственно, об этом и говорил: легкость «тут добавили репозиторий поверх EF, а тут — ApiController поверх репозитория» — она видимая, и в реальности неплохо бы учитывать тонкости тут, там и там.
Годная статья — узнал тренды. Но…

1. EF — не люблю ормы использую максимум мапер, но на это тему я уже холиварил…

2. Scaffolding — бред. Еще ни разу такое решение не работало. Всегда надо что то кастомное. Сейчас рулят бутстрапы — по сути готовая верстка, знай себе клепай вьюхи да процедуры. В случае написания админки просто идеально. Например twitter.github.com/bootstrap/index.html

3. Ninject. Я использую unity, но с ходу не нашел существенных отличий.

4. NLog. Высоко нагруженный сайт — хороший повод написать велосипед:) Логирование должно минимально влиять на производительность. Т.к. на прошлом проекте средней нагрузки log4net стал причиной тормозов, я не пожалел пары дней и написал свое логирование с шахматами и монашками.
Хотя NLog обязательно испытаю на проекте с меньшей нагрузкой.

5. PagedList — да о такой штуке сразу думаешь когда переходишь с WebForms, но по сути саму идею пейджинга для таблиц пора выкинуть на помойку. Добротный поиск — вот, что нужно пользователю.

6. Lucene.NET — интересная штука, надо посмотреть. Но вряд ли бы я отважился добавить это в реальный проект. И уж совсем не понятно как это может сравнится с мощью sql сервера.

7. На счет AspNetMembershipProvider это вы зря — нормальное решение для малых и средних проектов. Да процедуры написаны под sql 2000 потому и выглядят как дерьмо мамонта. Но процедуры из вашего примера используются лишь для редактирования пользователей. А вот для авторизации как раз все неплохо оптимизировано.

8. ASP.NET MVC4 Web API — да похоже ребята опять что то крутое готовят.
1. EF — больше, чем ORM. Как минимум Code First, оценил и полюбил эту штуку с первым же проектом, рекомендую!
2. Согласен. Генераторы на помойку. Хотя для быстрого создания прототипа, самое то.
3. Тоже самое.
4. NLog проявил себя неплохо. Но! Всё зависит от того, как настроен логгер и как он используется. Возможностей прострелить себе производительность масса.
5. Соглашусь. Пейджинг — олдскул и моветон. Кто лезет дальше 2-3 и последней страницы? :)
6. Чего так? Как раз вот думаю.
7. Мы честно пытались, не пригодился ни разу. Каждый проект со своими плюшками и пряниками. Только интерфейсы.
8. Мне честно говоря уже даже немного страшно за будущее ASP.NET MVC. Простота настораживает.
6. Lucene.NET — интересная штука, надо посмотреть. Но вряд ли бы я отважился добавить это в реальный проект. И уж совсем не понятно как это может сравнится с мощью sql сервера.

почему бы нет?
все данные для их целостности хранить в БД. параллельно можно интересующие поля также хранить и в Lucene, который по синтетическим тестам чуть ли не в 20 раз быстрее Full-Text Search'a, например, MS SQL.
кстати, Lucene также использует twitter.
Даже если поверить в тесты, что важнее в 20 раз быстрее или в 2 раза больше гемора при поддержке? Я ведь не пишу твиттер. Короче если и использовать Lucene то далеко не в каждом проекте.
Конечно, не в каждом — а там, где это нужно. У SQL Server-а, кстати, есть фича полнотекстового поиска.
спасибо кэп
Вот что пишут про Lucene (ну а Lucene.NET--его порт): Since we love Open Source here at Twitter we chose Lucene, a search engine library written in Java, as a starting point. После этого вы будете сомневаться, брать ли его на реальный проект?!
А также LinkedIn и многие другие.
1 и 2е у вас не вяжется. EF окромя того что ОРМ позволяет очень быстро прототипировать сайты, админки и всё прочее. Автоматические миграции вообще сказка. Скаффолдинг просто позволяет уменьшить количество нажатий. Собтсно то самое зачем Twitter Bootstrap юзают
6. Lucene.net можно сказать ядро RavenDb и с перформансом у них просто отлично.
Разница в том, что бутсрап это код который я не в коем случае не буду редактировать. Мне нужно просто прочитать инструкцию и использовать. А скаффолдинг это куча бесполезного кода который придется менять. Зачем? Я быстрее и качественней с нуля напишу.
Не напишете. Ведь вы даже не смотрите, как что написано, а пишете своё. Так, например, в скафолдинге можно менять T4 темплейты.

Но ведь что такое T4 вы не знаете, так как «зачем это нужно?». Вы раскритиковали несколько технологий, которые используются в промышленных масштабах. Такое позволительно лишь студентам, которые с интезиазмом берутся за написание пусть и кривого, но своего.

Максимум, чего от вас, как от человека в данной ситуации можно ожидать, так это то, что вы мельком прочтёте что такое T4, да какой-нибудь более детальный обзор о скафолдинге. Слов эдак на 300—400 и ввяжетесь в очередной спор «кастомное против готового».

Я искренне желаю вам не терять этой вашей энергии, но тратить её разумно.
Зачем мне менять T4 темплейты, если я могу просто писать код?

Знаю. Использование технологии в промышленных масштабах, не означает, что она лишена недостатков.

Кстати, действительно, не подумал об использовании скаффолдинга в качестве инструмента для обучения.
Вот только матерому профи не нужен весь этот нагенеренный мусор. Профи знает что, как и где написать, чтобы все было красиво, оптимально и без боли.

Да, я адепт кастомного и добротных компонентов. В кодогенерации разочаровался еще в студенчестве. Полуфабрикаты не люблю, когда использую подобное никак не могу отделаться от ощущения, что если бы написал все сам получилось бы все проще, быстрее и надежнее.
мощью sql сервера. — По сравнению с Lucene full-text search MS SQL убогий.
Ну я имел ввиду sql сервер как цельное решение. Может и убогий, но у нас неплохо справляется, а затрат на поддержку добавилось 0.
Full-text search + MS SQL для хорошей производительности требуют DBA, так что затраты на поддержку отличны от 0. Даже если DBA у вас нет то кто-то у вас периодически этим занимается и его время тоже стоит денег. И процедуры резервного копирования и железо на которое сбрасываются резервные копии тоже денег стоят. По сравнению с этим Lucene стоит копейки. Это не значит что стоит лепить Lucene всюду где можно и где нельзя, но когда я слышу что MS SQL это дёшово, мне сложно поверить. Дороже MS SQL разве только решения от Oracle и IBM.
Вопрос насчет CodeFirst: допустим он сгенерировал DB по моим классам, все работает. Потом я записал в эту DB реальные данные, а потом вдруг понял что мне нужно еще одно поле в таблице или нужно поменять его тип. Насколько я знаю, EF CodeFirst не умеет такие ситуации решать — прийдется пересоздавать таблицу по-новой, теряя данные. Получается что на реальных проектах EF CodeFirst не помогает а наоборот мешает работать, так как там такие проблемы (изменение структуры DB) возникают чуть ли не каждый день.

Теперь собственно вопрос — поменялось ли в этом плане что-нибудь в последних версиях EF?
хорошая новость — да, появились! начиная с версии 4.3. можно контролировать добавление/удаление/ изменение столбцов таблиц.
хороший пост об этом.
«Теперь собственно вопрос — поменялось ли в этом плане что-нибудь в последних версиях EF? „
Во-первых, поменялось. Появились миграции, которые позволяют менять структуру более мягко и контролируемо.

Во-вторых, и это более важно, CodeFirst не обязательно подразумевает управление структурой БД из кода. У нас вот доступ сделан через CodeFirst, потому что это удобно и прозрачно, но при этом все миграции/DbInitializerStrategy отключены вообще, а управление структурой БД идет вручную по отдельному процессу.
я не понимаю, зачем эта холиварщина, да еще поданная под таким соусом:
«Итак, определимся без каких пакетов нельзя начинать разрабатывать веб-приложение на ASP.NET MVC. „
Вы мне запрещаете? ок.
Почему не написать просто, вам нужен ORM (нужен?), log, ioc.
Code First может и ничего, но например изменение существующей схемы базы данных в последней виданной мной версии CF вызывал жуткую попуболь. В любом случае, в nHibernate есть Automapping, который ничем не хуже, а пожалуй даже и поудобнее Code First. Не говорю что nHiberante 100% лучше чем EF, но каждому свое, кому-то и linq2Sql за глаза хватит. Но думаю ваш авторитет вряд ли позволяет вам так однозначно утверждать что нужно пользоваться только EF.
То же самое с ninject (вам уже привели пяток ничем не худших альтернатив). К тому же не в любом и не в каждом web проекте ioc действительно необходим, незачем усложнять код без причин.
Почему Nlog а не log4net, даже не спрашиваю)
Ну и где тогда у вас например moq или rhinomocks — контроллеры не бум тестировать?
>>я не понимаю, зачем эта холиварщина, да еще поданная под таким соусом

честно, и намека нет. не делал даже сравнения с др. технологиями (java и пр.)

>>Вы мне запрещаете? ок.
>Почему не написать просто, вам нужен ORM (нужен?), log, ioc.

да Вы что? у меня НЕТ ПРАВА кому-либо, что-либо запрещать. можете начинать проект хоть с empty solution.

>>>Но думаю ваш авторитет вряд ли позволяет вам так однозначно утверждать что нужно пользоваться только EF.
я даже не заикнулся об этом. все же я НЕ являюсь истиной в последней инстанции. вся статья — это заметки с действующим кодом, с примерами. если Вы уже опытны, имеете свой арсенал любимых инструментов, то смело можете пропустить многие пункты. ибо на вкус и цвет...)

и да, я указал сразу же, что EF больше подходит именно для
>>>прототипирование слоя данных приложений стало одним удовольствием

забыл добавить:
>>>Ну и где тогда у вас например moq или rhinomocks — контроллеры не бум тестировать?

думал включать или нет тему тестирования. но для этого по объему нужна такая же статья. возможно напишу в следующей статье.

p.s.
и да, я адепт покрытия юнит-тестами большинства функционала.
>> Lucene (SimpleLucene) — поиск

Хорошее решение для поиска. Но не рекомендовал бы его «по умолчанию». Всё же не каждому решению нужен поиск и не всегда можно представить данные в виде одной денормилизированной таблицы для индекса Lucene. Часто встречаемая ситуация, когда есть связь данных many to many, особенно если A many to many B и B many to many С. А поиск нужен по полям всех трёх. Количество записей в индексе становится заоблачным, но всё же работает быстрее SQL запроса. Вот только памяти надо море и само индексирование рискует затянуться.
да, полностью хранить все в Lucene не стоит, ибо это не реляционная модель данных. основной упор именно полнотекстовый, либо недетерминированный поиск.
Интересно. Спасибо.

Возникло несколько вопросов, вы уж меня простите, если они покажутся глупыми. «Я ведь сварщик-то не настоящий, маску на стройке нашел...» ASP.NET MVC использую только для создания прототипов и всяких маленьких проектов, зачастую не сильно вдаваясь в подробности технологии, т.к. для меня важнее сделать быстро, по возможности приложив минимум усилий.

1. В примере про Entity Framework в контекте объявлен DbSet только для Category. Почему? Я бы в этом случае добавил бы DbSet и для Product. Это просто лишнее или в корне не верно?

2. MvcScaffolding для CRUD. Использую мастер AddController c соответсвующими опциями. В чем разница по сравнению с MvcScaffolding кроме командной строки / визуального мастера?

3. По поводу стандартного AspNetMembershipProvider. Вы не слишком категоричны? Повторюсь, что использую MVC только для создания прототипов и маленьких проектов. Для себя вижу проблемы только в профилях ползователей (дополнительная информация о пользователе). На данный момень использую стандартный Membership провайдер и свои профили, связывая их по username. Может быть подскажете какое-нибудь готовое решение?
1. Это не лишнее, нет. если необходим доступ ко всем продуктам, минуя слой категорий, то добавляйте новый DbSet. дело вкуса и необходимости.
2. дело в автоматизации кодогенерации (плюс меньше кликов).
3. AspNetMembershipProvider для именно маленьких проектов подойдет. готового решения не скажу, ибо не встречал.
совет — при создании запросов с стандартным AspNetMembershipProvider, делайте join по LoweredUserName, т.к. LoweredUserName находится в кластерном индексе для таблицы aspnet_users, а LoweredEmail в таблице aspnet_membership также в кластерном индексе.
Спасибо.

2. Но ведь мастер также все автоматически создает — и контроллер со всем необходимым, и представления. Или дело только в количестве кликов? Просто пытаюсь понять — надо оно мне, или и так хорошо.
хорошо, мастер создаст представления и контроллер, но без репозитория заодно, например.
а если изменилась модель? флаг -Force и скаффолдер пересоздаст все опять.
добавили POCO — и автоматически добавиться DbSet в DbContext + все остальное.
такого точно в мастере нет.
Вот теперь разобрался. Спасибо.
Вот далековат я от .NET, поэтому иногда возникает очень странное ощущение. Когда кто-то из дотнетчиков показывает, что, мол, раньше, смотрите, какая прорва кода нужна была, чтобы работало то-то и то-то. Смотришь — и правда простыня кода огромная. А теперь мол, смотрите, как все легко и просто. Смотришь — а там кода, конечно, меньше, но ведь все-равно ж дохрена!

И вот не знаешь, как реагировать: то ли радоваться, то ли печалиться. Видимо, нет предела совершенствованию — всегда все можно упростить еще.

(Относится не только к .NET)
лично я не встречал еще технологии, где бы вызов метода DoMagic() исполнил бы все желания, а Вы?)
Правильно подсказывают knockoutjs
Также еще можно ограниченно рекомендовать mongodb — mongodb — C# — knockoutjs очень хорошо сочетаются.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации