Re: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 13.09.17 15:25
Оценка: +2 -1
Здравствуйте, Shmj, Вы писали:

S>Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?


Когда-то часто совмещал. Но оказалось, что 90% — цифра весьма временная и с развитием проекта стремится к 09%, что делает такое решение не только безсмысленным, но даже вредным. А не меняется эта цифра только в мёртвых проектах.
Если нам не помогут, то мы тоже никого не пощадим.
Re[5]: В сотый раз про сущности EF и бизнес-объекты...
От: Danchik Украина  
Дата: 21.09.17 08:09
Оценка: 36 (1) +1
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, IT, Вы писали:


IT>>Про сложные запросы промолчу, это видимо выше всякого понимания.


Doc>Продолжайте писать сложные запросы с логикой на EF. Удачи


И это вы автору linq2db написали

IT>>Но чем большие объёмы противоречат LINQ? И какие объёмы считаются большими?


Doc>Тут согласен с вопросом, т.к. я не корректно выразился. Речь про ситуации, когда надо обработать большие объемы данных, но при этом результатом является некая небольшая сводка/статистика.


Сложные SQL прекрасно пишутся на linq2db без голого SQL.
К примеру, самыми сложными я бы их не назвал, но все же: здесь
Были переписал представления Northwind на linq2db для тестирования производительности парсера. Все прошло чудесно.
А здесь можно увидеть как я на "view" сделал join.
Вот и SQL для VwSalesByCategory
-- Northwind SqlServer.2012
DECLARE @year1 Int -- Int32
SET     @year1 = 2015

SELECT
    [c3].[CategoryID],
    [c3].[CategoryName],
    [p2].[ProductName],
    Sum([ode].[c1]) as [c2]
FROM
    [dbo].[Categories] [c3]
        INNER JOIN [dbo].[Products] [p2] ON [c3].[CategoryID] = [p2].[CategoryID]
        INNER JOIN [dbo].[Orders] [o2]
            INNER JOIN (
                SELECT DISTINCT
                    [t2].[OrderID],
                    [t2].[ProductID],
                    [t1].[ProductName] as [ProductName1],
                    [t2].[UnitPrice],
                    [t2].[Quantity],
                    [t2].[Discount],
                    Round(([t2].[UnitPrice] * Convert(Decimal(29,10), [t2].[Quantity])) * (1 - Convert(Decimal(29,10), [t2].[Discount])), 2) as [c1]
                FROM
                    [dbo].[Order Details] [t2]
                        INNER JOIN [dbo].[Products] [t1] ON [t2].[ProductID] = [t1].[ProductID]
            ) [ode] ON [o2].[OrderID] = [ode].[OrderID]
        ON [p2].[ProductID] = [ode].[ProductID]
WHERE
    DatePart(Year, [o2].[OrderDate]) = @year1
GROUP BY
    [c3].[CategoryID],
    [c3].[CategoryName],
    [p2].[ProductName]

И зачем мне теперь SQL, склейка строк, параметры, сложность поддержки?
Re[5]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 21.09.17 13:38
Оценка: +2
Здравствуйте, Doc, Вы писали:

IT>>Про сложные запросы промолчу, это видимо выше всякого понимания.

Doc>Продолжайте писать сложные запросы с логикой на EF. Удачи

Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?
Если нам не помогут, то мы тоже никого не пощадим.
Re: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 20.09.17 04:24
Оценка: -1
Здравствуйте, Shmj, Вы писали:

S>Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?


Для небольшого проекта на скорую руку может и пойдет. Для серьезного — я все же предпочел бы разделить доступ к данным и бизнес логику.
1) Понятнее архитектура проекта
2) Легче сопровождать когда каждая часть проекта занята только своей задачей
3) Легко могут появиться новые типы хранилищ (например NoSQL типа Redis, Azure Table Storage и т. д.). DAL может это легко скрыть от BL (BL вообще не должно волновать где и как хранятся данные)
4) Даже в SQL хранилище структура может отличаться от структуры BL
Re[3]: В сотый раз про сущности EF и бизнес-объекты...
От: Danchik Украина  
Дата: 20.09.17 07:41
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, Danchik, Вы писали:


S>>>Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?


D>>Что значит специальные сущности? Code First?


S>Он самый.


Для меня Database First, что ни на есть самое эфективное в продакшине.

D>>У вас есть база данных, от нее и пляшем. Практика показывает, что лучше не полениться и написать ручками. Все равно стахановские реализации придется править, особенно когда поймете какое EF г-но.


S>А что не г-но?


linq2db же тут ты не найдешь Code First ни Change Tracking. Зато эфективность запросов можешь контролировать сам, а скорость маппинга обганяет Dapper.
Не конкретно о вас, но, печально, что в наше время програмисты практически не разбираются в SQL и просят от ORM ну несусветного результата от десятиэтажного linq query
Re[2]: В сотый раз про сущности EF и бизнес-объекты...
От: Danchik Украина  
Дата: 20.09.17 07:44
Оценка: +1
Здравствуйте, Doc, Вы писали:

Doc>Здравствуйте, Shmj, Вы писали:


S>>Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?


Doc>Для небольшого проекта на скорую руку может и пойдет. Для серьезного — я все же предпочел бы разделить доступ к данным и бизнес логику.

Doc>1) Понятнее архитектура проекта
Doc>2) Легче сопровождать когда каждая часть проекта занята только своей задачей
Doc>3) Легко могут появиться новые типы хранилищ (например NoSQL типа Redis, Azure Table Storage и т. д.). DAL может это легко скрыть от BL (BL вообще не должно волновать где и как хранятся данные)
Doc>4) Даже в SQL хранилище структура может отличаться от структуры BL

И поетому проект становится большим и тормознутым
Я бы так категорично обо всех проектах не говорил. Лишняя абстракция часто мешает чем помогает.
Re[4]: В сотый раз про сущности EF и бизнес-объекты...
От: MozgC США http://nightcoder.livejournal.com
Дата: 20.09.17 15:21
Оценка: +1
Здравствуйте, IT, Вы писали:

Doc>>Разумеется есть задачи, где сразу видно что нужен SQL (сложные запросы, большие объемы данных).

IT>Про сложные запросы промолчу, это видимо выше всякого понимания. Но чем большие объёмы противоречат LINQ? И какие объёмы считаются большими?

Возможно он это пишет на основе опыта работы с EF. Я не знаю как себя ведёт EF на больших проектах, я с ним только игрался. У нас на проекте linq2db используется с базой в несколько террабайт. Полёт отличный.
Re[7]: В сотый раз про сущности EF и бизнес-объекты...
От: Max Mustermann  
Дата: 22.09.17 08:39
Оценка: +1
Здравствуйте, Doc, Вы писали:

IT>>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?

Doc>В таких ситуациях EF 6 склонен выдавать не оптимальные SQL запросы. На практике, то же самое — сделанное на SQL работает в разы быстрее.

Без конкретных примеров это просто сотрясание воздуха.
Это даже не считая того, что есть масса "доказаных" случаев, когда EF за счёт разбора expression tree выдаёт sql гораздо лучше "рукописного".
Re[9]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 22.09.17 14:17
Оценка: +1
Здравствуйте, Shmj, Вы писали:

IT>>При чём тут это? Я спрашиваю, какие проблемы в EF ведут к тому, что оно не может обрабатывать сложные запросы? Мне правда интересно.

S>Ограниченность вестимо. Есть ли в EF поддержка курсоров SQL? Насколько я знаю -- нет.

Курсоры и производительность по идее никак не связаны между собой. Разве что на курсорах обычно в перспективе получаются более тормозные рещения
Если нам не помогут, то мы тоже никого не пощадим.
Re[11]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 22.09.17 17:43
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Да, вы скажите что так делать не правильно, нужно полностью переработать архитектуру.


Конечно, скажу. Ещё скажу, что приведённый пример не демонстрирует сильную стороную курсоров, а как раз наоборот, демонстрирует их неумелое использование. Курсоры в отчётах?

S>Если вместо курсоров дергать по 1 записи из C#-кода -- будет отрабатывать не 2 часа а 2 дня.


Не надо дёргать курсоры, надо от них избавляться. Чаще всего курсоры используются как заменитель понимания и умения оперировать последовательностями данных, умения использовать SQL. Курсоры просты в понимании, просто крутим цикл и готово. Поэтому, правильное переписывание этих отчётов дало бы не 2 дня вместо 2-х часов, а 20 минут в худшем случае.

S>Да, проблема в архитектуре. Но иногда архитектура не подлежит изменению.


Если что-то не подлежит изменению, то это не означает, что то, что изменению подлежит должно делаться в рамках той же самой архитектуры.
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: Слава  
Дата: 24.09.17 23:20
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>При чём тут это? Я спрашиваю, какие проблемы в EF ведут к тому, что оно не может обрабатывать сложные запросы? Мне правда интересно.


EF позволяет грузить объекты целиком, вместо кортежей, это приводит к желанию понаписать include'ов, после чего возникает следующее,
  Проблема 1:
 private IQueryable<FuelDispenser> LoadDispensers()
        {
            return _repositoryFactory.GetRepository<FuelDispenser>().Query()
                .Include(d => d.FuelDispenserController)
                .Include(d => d.Equipment)
                .Include(d => d.FuelDispenserController.FuelDispenserSet)
                .Include(d => d.FuelTank)
                .Include(d => d.FuelTank.Fuel)
                .Include(d => d.FuelTank.Fuel.Petrochemical)
                .Include(d => d.FuelDispenserSide)
                .Include(d => d.Equipment.Workplace);
        }

  Что в свою очередь конструирует запрос
SELECT
"B"."Id" AS "Id",
"B"."Number" AS "Number",
"B"."FuelDispenserControllerId" AS "FuelDispenserControllerId",
"B"."EquipmentId" AS "EquipmentId",
"B"."FuelTankId" AS "FuelTankId",
"B"."SideId" AS "SideId",
"B"."SortOrder" AS "SortOrder",
"C"."Id" AS "Id1",
"C"."Number" AS "Number1",
"C"."DispenserSetId" AS "DispenserSetId",
"E"."Id" AS "Id2",
"E"."Number" AS "Number2",
"E"."SortOrder" AS "SortOrder1",
"G"."Id" AS "Id3",
"G"."FuelId" AS "FuelId",
"G"."Number" AS "Number3",
"G"."FuelVolumeCalculated" AS "FuelVolumeCalculated",
"G"."Temperature" AS "Temperature",
"G"."Density" AS "Density",
"G"."FuelWeightFact" AS "FuelWeightFact",
"G"."FuelWeightCalculated" AS "FuelWeightCalculated",
"G"."MaxUpperDensity" AS "MaxUpperDensity",
"G"."MinLowerDensity" AS "MinLowerDensity",
"G"."ZondId" AS "ZondId",
"G"."FuelLevelCalculated" AS "FuelLevelCalculated",
"G"."FuelLevelFact" AS "FuelLevelFact",
"G"."FuelVolumeFact" AS "FuelVolumeFact",
"G"."DeadFuelLevel" AS "DeadFuelLevel",
"G"."UpperFuelLevel" AS "UpperFuelLevel",
"G"."MaxUpperFuelLevel" AS "MaxUpperFuelLevel",
"G"."LowerFuelLevel" AS "LowerFuelLevel",
"G"."MinLowerFuelLevel" AS "MinLowerFuelLevel",
"G"."MaxUpperWaterLevel" AS "MaxUpperWaterLevel",
"G"."WaterLevel" AS "WaterLevel",
CASE WHEN ("I"."Id" IS NULL) THEN NULL ELSE CAST(_UTF8'8X0X' AS
VARCHAR(8191)) END AS "C1",
"I"."Id" AS "Id4",
"I"."Price" AS "Price",
"I"."PetrochemicalId" AS "PetrochemicalId",
CASE WHEN ("M"."Id" IS NULL) THEN NULL ELSE CAST(_UTF8'10X0X' AS
VARCHAR(8191)) END AS "C2",
"M"."Id" AS "Id5",
"M"."Value" AS "Value",
"M"."Description" AS "Description",
"M"."IsArchived" AS "IsArchived",
"M"."Color" AS "Color",
"M"."SortNumber" AS "SortNumber",
NULL AS "C3",
NULL AS "C4",
NULL AS "C5",
NULL AS "C6",
"O"."Id" AS "Id6",
"O"."Number" AS "Number4",
"O"."X" AS "X",
"O"."Y" AS "Y",
"O"."FuelDispenserSetId" AS "FuelDispenserSetId",
"Q"."Id" AS "Id7",
"Q"."EquipmentType" AS "EquipmentType",
"Q"."Name" AS "Name",
"Q"."Path" AS "Path",
"Q"."WorkplaceId" AS "WorkplaceId",
CASE WHEN ("S"."Id" IS NULL) THEN NULL WHEN ("S"."Identity" =
CAST(_UTF8'PETROL' AS VARCHAR(30))) THEN CAST(_UTF8'10X0X' AS
VARCHAR(8191)) WHEN ("S"."Identity" = CAST(_UTF8'TTYPE' AS
VARCHAR(30))) THEN CAST(_UTF8'10X1X' AS VARCHAR(8191)) WHEN
("S"."Identity" = CAST(_UTF8'TKIND' AS VARCHAR(30))) THEN
CAST(_UTF8'10X2X' AS VARCHAR(8191)) WHEN ("S"."Identity" =
CAST(_UTF8'WORKPLACE' AS VARCHAR(30))) THEN CAST(_UTF8'10X3X' AS
VARCHAR(8191)) WHEN ("S"."Identity" = CAST(_UTF8'CONTRAGENT_TYPE' AS
VARCHAR(30))) THEN CAST(_UTF8'10X4X' AS VARCHAR(8191)) WHEN
("S"."Identity" = CAST(_UTF8'PERMISSION' AS VARCHAR(30))) THEN
CAST(_UTF8'10X5X' AS VARCHAR(8191)) WHEN ("S"."Identity" =
CAST(_UTF8'CNTRGT_GROUP' AS VARCHAR(30))) THEN CAST(_UTF8'10X6X' AS
VARCHAR(8191)) WHEN ("S"."Identity" = CAST(_UTF8'DISCONT_CND' AS
VARCHAR(30))) THEN CAST(_UTF8'10X7X' AS VARCHAR(8191)) ELSE
CAST(_UTF8'10X8X' AS VARCHAR(8191)) END AS "C7",
"S"."Id" AS "Id8",
"S"."Value" AS "Value1",
"S"."Description" AS "Description1",
"S"."IsArchived" AS "IsArchived1",
"S"."Color" AS "Color1",
"S"."SortNumber" AS "SortNumber1",
"S"."IsServer" AS "IsServer",
"S"."SelfServiceTerminalId" AS "SelfServiceTerminalId",
"S"."PermissionCategory" AS "PermissionCategory",
"S"."IsSheduled" AS "IsSheduled"
FROM          "FuelDispenser" AS "B"
INNER JOIN "FuelDispenserController" AS "C" ON
"B"."FuelDispenserControllerId" = "C"."Id"
INNER JOIN "FuelDispenserSet" AS "E" ON "C"."DispenserSetId" = "E"."Id"
INNER JOIN "FuelTank" AS "G" ON "B"."FuelTankId" = "G"."Id"
LEFT OUTER JOIN "BaseMerchant" AS "I" ON ("G"."FuelId" = "I"."Id") AND
("I"."Identity" = CAST(_UTF8'FUEL' AS VARCHAR(10)))
LEFT OUTER JOIN "BaseMerchant" AS "K" ON ("G"."FuelId" = "K"."Id") AND
("K"."Identity" = CAST(_UTF8'FUEL' AS VARCHAR(10)))
LEFT OUTER JOIN "BaseCatalogItem" AS "M" ON ("K"."PetrochemicalId" =
"M"."Id") AND ("M"."Identity" = CAST(_UTF8'PETROL' AS VARCHAR(30)))
INNER JOIN "FuelDispenserSide" AS "O" ON "B"."SideId" = "O"."Id"
INNER JOIN "Equipment" AS "Q" ON "B"."EquipmentId" = "Q"."Id"
LEFT OUTER JOIN "BaseCatalogItem" AS "S" ON ("Q"."WorkplaceId" =
"S"."Id") AND (((("S"."Identity" = CAST(_UTF8'PETROL' AS VARCHAR(30)))
OR ("S"."Identity" = CAST(_UTF8'CONTRAGENT_TYPE' AS VARCHAR(30)))) OR
(("S"."Identity" = CAST(_UTF8'PERMISSION' AS VARCHAR(30))) OR
("S"."Identity" = CAST(_UTF8'WORKPLACE' AS VARCHAR(30))))) OR
((("S"."Identity" = CAST(_UTF8'CNTRGT_GROUP' AS VARCHAR(30))) OR
("S"."Identity" = CAST(_UTF8'DISCONT_CND' AS VARCHAR(30)))) OR
((("S"."Identity" = CAST(_UTF8'PRICEING_TYPE' AS VARCHAR(30))) OR
("S"."Identity" = CAST(_UTF8'TKIND' AS VARCHAR(30)))) OR
("S"."Identity" = CAST(_UTF8'TTYPE' AS VARCHAR(30))))))
При выполнении этого запроса на подключении с юникодом возникает такая ошибка:

Dynamic SQL Error
SQL error code = -204
Implementation limit exceeded
block size exceeds implementation restriction

Означающую, что у Файрберда оно в рот не помещается. Если же работать не в юникоде, то запрос вида WHERE Name='Системный пользователь' не работает в принципе.


...и вышли из тыих олтарей мыши, крыски, усеницы, мошь, вша красная,
вша жолтая, и иные всякие твари, и несли гробы повапленные со свещами
унутри, и float в трех байтах, и null-терминированные строки, и горы
кода на дельфях, и доморощенные бинарные протоколы

Проблема 2:
Затем там отказались от Firebird и перешли на MSSQL Express, но: энергичные объектно-ориентированные программисты энергично пишут дохера кода, который через WCF выгребает кучу данных в объектном виде (EF->domain->DTO->WCF->linq->Telerik) и объединяет их на клиенте, да и на сервере при выборке оно тоже тормозит, и еще бы ему не тормозить, при 15 тысячах запросов, которые делаются из одного. В результате, мой код с рукопашным отчётом на FlowDocument и linq2db работал секунды две, а Объектно-Ориентированная Слойка с отчётами телерика скрипела примерно минут сорок.

PS: Слава богу, что я там больше не работаю.
Re[10]: В сотый раз про сущности EF и бизнес-объекты...
От: IB Австрия http://rsdn.ru
Дата: 25.09.17 13:37
Оценка: +1
Здравствуйте, IT, Вы писали:

IT>Можно пример когда EF генерирует что-то непотребное? А то у меня большие сомнения.

http://rsdn.org/forum/flame.comp/5670024.1
Автор: IB
Дата: 01.07.14
Мы уже победили, просто это еще не так заметно...
В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 12.09.17 04:43
Оценка:
Много где обсуждалось. Но хотелось бы конкретики.

А именно. Чем плоха такая схема:

1. Для сервисов и их данных создаются контракты (interface). Интерфейсы принимают и отдают тоже интерфейсы или примитивные типы. Нужно для простой возоможности тестирования (подмена тех или иных сервисов на тестовую реализацию) и для возможности более простого распараллеливания работы.

2. Уже при реализации интерфейсов создаются классы бизнес-объектов (на основе соответствующих интерфейсов, просто нажимаешь правой кнопочкой implement).

Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?

Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?
Re: В сотый раз про сущности EF и бизнес-объекты...
От: Danchik Украина  
Дата: 12.09.17 10:21
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Много где обсуждалось. Но хотелось бы конкретики.


S>А именно. Чем плоха такая схема:


S>1. Для сервисов и их данных создаются контракты (interface). Интерфейсы принимают и отдают тоже интерфейсы или примитивные типы. Нужно для простой возоможности тестирования (подмена тех или иных сервисов на тестовую реализацию) и для возможности более простого распараллеливания работы.


>принимают и отдают тоже интерфейсы


Возможно имеет смысл.

S>2. Уже при реализации интерфейсов создаются классы бизнес-объектов (на основе соответствующих интерфейсов, просто нажимаешь правой кнопочкой implement).


S>Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?


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

S>Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?


Что значит специальные сущности? Code First?
У вас есть база данных, от нее и пляшем. Практика показывает, что лучше не полениться и написать ручками. Все равно стахановские реализации придется править, особенно когда поймете какое EF г-но.
Re: В сотый раз про сущности EF и бизнес-объекты...
От: vorona  
Дата: 12.09.17 10:25
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?


Можно использовать Fluent Api
Re[2]: В сотый раз про сущности EF и бизнес-объекты...
От: s_aa Россия  
Дата: 12.09.17 16:55
Оценка:
D>Что значит специальные сущности? Code First?
D>У вас есть база данных, от нее и пляшем. Практика показывает, что лучше не полениться и написать ручками. Все равно стахановские реализации придется править, особенно когда поймете какое EF г-но.

Небольшие программы вполне комфортно писать Code First, а таких полно во внутренней автоматизации.
Жизнь не обязана доставлять удовольствие. Достаточно отсутствия страданий.
Re[2]: В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 13.09.17 04:41
Оценка:
Здравствуйте, Danchik, Вы писали:

S>>Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?


D>Что значит специальные сущности? Code First?


Он самый.

D>У вас есть база данных, от нее и пляшем. Практика показывает, что лучше не полениться и написать ручками. Все равно стахановские реализации придется править, особенно когда поймете какое EF г-но.


А что не г-но?
Re: В сотый раз про сущности EF и бизнес-объекты...
От: karbofos42 Россия  
Дата: 13.09.17 05:45
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Много где обсуждалось. Но хотелось бы конкретики.


S>А именно. Чем плоха такая схема:


S>1. Для сервисов и их данных создаются контракты (interface). Интерфейсы принимают и отдают тоже интерфейсы или примитивные типы. Нужно для простой возоможности тестирования (подмена тех или иных сервисов на тестовую реализацию) и для возможности более простого распараллеливания работы.


S>2. Уже при реализации интерфейсов создаются классы бизнес-объектов (на основе соответствующих интерфейсов, просто нажимаешь правой кнопочкой implement).


S>Вопрос: чем плохо эти же классы бизнес-объектов наделить атрибутами разными, в том числе Key, Index, Required и пр. и позволить им сохраняться/восстанавливаться через EF? Какие конкретные минусы?


S>Стали бы вы делать специальные сущности для EF, которые на 90% совпадают с бизнес-объектами?


Создавать интерфейсы для бизнес-объектов — это как-то перебор. Тестированию они и так не мешают, профита не вижу.
По поводу атрибутов: они всё же больше для слоя доступа к данным относятся, не совсем им место в модели. Где-то приемлемо атрибуты прописать, где-то лучше через FluentAPI задать в контексте, чтобы всё было там, где должно быть.
Re[2]: В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 13.09.17 06:12
Оценка:
Здравствуйте, karbofos42, Вы писали:

K>Создавать интерфейсы для бизнес-объектов — это как-то перебор. Тестированию они и так не мешают, профита не вижу.

K>По поводу атрибутов: они всё же больше для слоя доступа к данным относятся, не совсем им место в модели. Где-то приемлемо атрибуты прописать, где-то лучше через FluentAPI задать в контексте, чтобы всё было там, где должно быть.

Так в том то и фишка -- если BO не через интерфейсы -- то получается что атрибуты данных не к месту. А если через интерфейсы -- то реализация конкретная может создавать какие угодно свои атрибуты и вспомогательные поля -- оно никак не нарушает договоренности.

Если не интерфейс -- то получается постоянное копирование из бизнес-объектов в сущености EF и обратно. А нафиг эта лишняя глупая работа?
Re[3]: В сотый раз про сущности EF и бизнес-объекты...
От: karbofos42 Россия  
Дата: 13.09.17 13:58
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Здравствуйте, karbofos42, Вы писали:


K>>Создавать интерфейсы для бизнес-объектов — это как-то перебор. Тестированию они и так не мешают, профита не вижу.

K>>По поводу атрибутов: они всё же больше для слоя доступа к данным относятся, не совсем им место в модели. Где-то приемлемо атрибуты прописать, где-то лучше через FluentAPI задать в контексте, чтобы всё было там, где должно быть.

S>Так в том то и фишка -- если BO не через интерфейсы -- то получается что атрибуты данных не к месту. А если через интерфейсы -- то реализация конкретная может создавать какие угодно свои атрибуты и вспомогательные поля -- оно никак не нарушает договоренности.


S>Если не интерфейс -- то получается постоянное копирование из бизнес-объектов в сущености EF и обратно. А нафиг эта лишняя глупая работа?


Мне кажется, что наоборот с интерфейсами будет всё сложнее, запутаннее и больше лишней работы.

Получается, что интерфейсы — это вроде BO, а реализация интерфейсов с проставленными атрибутами — это уже ближе к DAL.
Вместо маппинга между классами BO и классами-сущностей EF получатся классы, которые внутри себя будут маппить свойства и нести двойной функционал — и представление структуры БД для EF и реализация интерфейса BO.
Моё мнение — там где есть реляционная БД + ORM — там всегда будет глупая лишняя работа, т.к. будет натягивание ежа на ужа.
Re[2]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 20.09.17 04:31
Оценка:
Здравствуйте, Danchik, Вы писали:

D>У вас есть база данных, от нее и пляшем. Практика показывает, что лучше не полениться и написать ручками. Все равно стахановские реализации придется править, особенно когда поймете какое EF г-но.


Ну так пишите без него IMHO EF решает свою задачу: изначально DAL может использовать EF для доступа (с его помощью быстрее писать чем на чистом SQL, и нет необходимости привлечения SQL профи). Разумеется есть задачи, где сразу видно что нужен SQL (сложные запросы, большие объемы данных).

Далее мониторим где узкое место это запросы EF, и переписываем на SQL. DAL делает все это "прозрачным" для BL. Писать все сразу на SQL — это по сути преждевременная оптимизация. В большинстве случаев, выигрыш будет очень не значительным и не будет стоить затраченных на SQL усилий.
Re[3]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 20.09.17 10:37
Оценка:
Здравствуйте, Danchik, Вы писали:

D>И поетому проект становится большим и тормознутым


Но проект при этом работает, решает задачи и имеет больший функционал, пока кто-то пишет DAL на SQL с нуля
Да и тормознутым не будет, т.к. что надо — переводится в SQL или вообще в более оптимальное хранилище.
Re[3]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 20.09.17 15:03
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Разумеется есть задачи, где сразу видно что нужен SQL (сложные запросы, большие объемы данных).


Про сложные запросы промолчу, это видимо выше всякого понимания. Но чем большие объёмы противоречат LINQ? И какие объёмы считаются большими?
Если нам не помогут, то мы тоже никого не пощадим.
Re[4]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 21.09.17 06:40
Оценка:
Здравствуйте, IT, Вы писали:

IT>Про сложные запросы промолчу, это видимо выше всякого понимания.


Продолжайте писать сложные запросы с логикой на EF. Удачи

IT>Но чем большие объёмы противоречат LINQ? И какие объёмы считаются большими?


Тут согласен с вопросом, т.к. я не корректно выразился. Речь про ситуации, когда надо обработать большие объемы данных, но при этом результатом является некая небольшая сводка/статистика.
Re[6]: В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 21.09.17 19:12
Оценка:
Здравствуйте, IT, Вы писали:

IT>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?


При использовании так нелюбимого многими паттерна Repository и UnitOfWork можно без боли медленный метод перенести в хранимую процедуру.
Re[7]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 22.09.17 04:57
Оценка:
Здравствуйте, Shmj, Вы писали:

IT>>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?

S>При использовании так нелюбимого многими паттерна Repository и UnitOfWork можно без боли медленный метод перенести в хранимую процедуру.

При чём тут это? Я спрашиваю, какие проблемы в EF ведут к тому, что оно не может обрабатывать сложные запросы? Мне правда интересно.
Если нам не помогут, то мы тоже никого не пощадим.
Re[6]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 22.09.17 05:37
Оценка:
Здравствуйте, Danchik, Вы писали:

D>И это вы автору linq2db написали


Да хоть разработчику самого .NET. Дальше что?
Рекомендую поглядеть на название топика и глянуть обсуждения. Мы про linq2db или про EF тут?
Re[6]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 22.09.17 05:45
Оценка:
Здравствуйте, IT, Вы писали:

IT>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?


В таких ситуациях EF 6 склонен выдавать не оптимальные SQL запросы. На практике, то же самое — сделанное на SQL работает в разы быстрее.
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 22.09.17 07:45
Оценка:
Здравствуйте, IT, Вы писали:

IT>При чём тут это? Я спрашиваю, какие проблемы в EF ведут к тому, что оно не может обрабатывать сложные запросы? Мне правда интересно.


Ограниченность вестимо. Есть ли в EF поддержка курсоров SQL? Насколько я знаю -- нет.
Re[7]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 22.09.17 13:30
Оценка:
Здравствуйте, Doc, Вы писали:

IT>>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?

Doc>В таких ситуациях EF 6 склонен выдавать не оптимальные SQL запросы. На практике, то же самое — сделанное на SQL работает в разы быстрее.

Ты хочешь сказать, что EF умничает и генерирует не то, что написал программист?
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: В сотый раз про сущности EF и бизнес-объекты...
От: Shmj Ниоткуда  
Дата: 22.09.17 17:07
Оценка:
Здравствуйте, IT, Вы писали:

IT>Курсоры и производительность по идее никак не связаны между собой. Разве что на курсорах обычно в перспективе получаются более тормозные рещения


У меня самая первая работа была, так там прога для бухгалтерии, в которой было около 1000 таблиц. Да, епта, 1000 таблиц. И помоему 15 тыс. хранимых процедур (90% из которых автогенеренные, конечно).

Так вот во многих процедурах происходила обработка данных, типа генерации отчетов за период и пр. И делалось это с помощью временных таблиц и курсоров. Бралось по одной записи, получали вспомогательные данные из связанных таблиц, передавали в другие процедуры и на выходе получали нужные данные. Такой запрос мог работать и 2 часа.

Да, вы скажите что так делать не правильно, нужно полностью переработать архитектуру. Но когда посмотришь на эти 1000 таблиц и список хранимых процедур, которые даже обозрить нельзя -- то мысль о переработке архитектуры отпадает.

Если вместо курсоров дергать по 1 записи из C#-кода -- будет отрабатывать не 2 часа а 2 дня.

Да, проблема в архитектуре. Но иногда архитектура не подлежит изменению.
Re[6]: В сотый раз про сущности EF и бизнес-объекты...
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 24.09.17 19:56
Оценка:
Здравствуйте, IT, Вы писали:

IT>Мне даже интересно, что же такого в EF неправильного, что в нём не следует писать сложные запросы? Можешь как-то сформулировать проблему?


Главное что в EF неправильно — сама идея менять объекты с трекингом где то за сценой, а потом эти изменения пучком сбрасывать. Из-за этого мозги у девелоперов начинают работать неправильно, и на выходе получается код с кучей спецэффектов и кривые выборки, так как для изменений нужны целиковые объекты, а проекции не катят. Рефакторить такое потом — жуткий ад.
Что же касается чистых запросов — тут я сам теряюсь в догадках.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 25.09.17 03:45
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ты хочешь сказать, что EF умничает и генерирует не то, что написал программист?


Где я такое сказал? А из твоих слов можно подумать что есть только один способ получения заданного результата

Ок, сформулирую еще раз: EF генерирует то, что в итоге выдает требуемый результат. Но т.к. результат можно достичь разными способами, то EF иногда выдает не самый оптимальный из них.
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 25.09.17 03:49
Оценка:
Здравствуйте, Max Mustermann, Вы писали:

MM>Это даже не считая того, что есть масса "доказаных" случаев, когда EF за счёт разбора expression tree выдаёт sql гораздо лучше "рукописного".


И как это отменяет того, что EF может генерировать не оптимальный код в некоторых случаях.
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 25.09.17 04:21
Оценка:
Здравствуйте, Max Mustermann, Вы писали:

MM>Без конкретных примеров это просто сотрясание воздуха.


Ну например, надо удалить записи попадающие под некое условие (и таких записей может быть очень много).
Re[9]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 25.09.17 04:27
Оценка:
Здравствуйте, Слава, Вы писали:

С>Затем там отказались от Firebird и перешли на MSSQL Express, но: энергичные объектно-ориентированные программисты энергично пишут дохера кода, который через WCF выгребает кучу данных в объектном виде (EF->domain->DTO->WCF->linq->Telerik) и объединяет их на клиенте, да и на сервере при выборке оно тоже тормозит, и еще бы ему не тормозить, при 15 тысячах запросов, которые делаются из одного. В результате, мой код с рукопашным отчётом на FlowDocument и linq2db работал секунды две, а Объектно-Ориентированная Слойка с отчётами телерика скрипела примерно минут сорок.


Ну это вряд ли проблема EF. Это скорее как обычно проблема в "орхетиктуре".
Если нам не помогут, то мы тоже никого не пощадим.
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: IB Австрия http://rsdn.ru
Дата: 25.09.17 11:03
Оценка:
Здравствуйте, Max Mustermann, Вы писали:

MM>Без конкретных примеров это просто сотрясание воздуха.

Вам надо примеров — их есть у меня.
Во всех случаях запросов один-ко-многим, EF строит план, примерно в два раза хуже оптимального, так как ему нужно выгрести дополнительные метаданные, что выливается в лишний подзапрос, который приложению нафиг не нужен.
http://rsdn.org/forum/flame.comp/5670024.1
Автор: IB
Дата: 01.07.14

И я сильно удивлюсь, если запросов с left join в приложении меньше половины. Иными словами, минимум половина запросов в приложении выполняется в два раза медленнее чем могло бы, просто потому что EF.

MM>Это даже не считая того, что есть масса "доказаных" случаев, когда EF за счёт разбора expression tree выдаёт sql гораздо лучше "рукописного".

Hard to believe. Он просто архитектурно устроен так, что оптимизировать именно на уровне expression tree крайне затруднительно, слишком много уровней абстракции внутри.
Мы уже победили, просто это еще не так заметно...
Re[8]: В сотый раз про сущности EF и бизнес-объекты...
От: IB Австрия http://rsdn.ru
Дата: 25.09.17 11:05
Оценка:
Здравствуйте, IT, Вы писали:

IT>Ты хочешь сказать, что EF умничает и генерирует не то, что написал программист?

Да. Ему нужны еще дополнительные метаданные для каких-то своих внутренних нужд и для этого он лепит дополнительные подзапросы.
Мы уже победили, просто это еще не так заметно...
Re[7]: В сотый раз про сущности EF и бизнес-объекты...
От: IB Австрия http://rsdn.ru
Дата: 25.09.17 11:17
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Что же касается чистых запросов — тут я сам теряюсь в догадках.

Основная проблема с EF в том, что там нет чистых запросов. Изначально, как ты помнишь, он делался как всемогутер, работающий через промежуточный слой. А слой этот представляет из себя некую абстрактную объектную модель, которая знает как мапить объекты на таблицы и обратно, в результате, все маппинги и запросы так и ходят через эту прослойку. Даже когда стало понятно, что такой подход не работает, отключить ее толком не удалось, только скрыть от прикладных разработчиков, а так все по прежнему работает через этот дымоход. Там же до сих пор хвосты ObjectSpaces торчат.
Отсюда и все косяки с EF.
Мы уже победили, просто это еще не так заметно...
Re[9]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 25.09.17 13:08
Оценка:
Здравствуйте, Doc, Вы писали:

IT>>Ты хочешь сказать, что EF умничает и генерирует не то, что написал программист?

Doc>Где я такое сказал? А из твоих слов можно подумать что есть только один способ получения заданного результата

Вообще-то, да. Так вот чтобы нагенерировать всякой отсебятины нужно постараться.

Doc>Ок, сформулирую еще раз: EF генерирует то, что в итоге выдает требуемый результат. Но т.к. результат можно достичь разными способами, то EF иногда выдает не самый оптимальный из них.


Можно пример когда EF генерирует что-то непотребное? А то у меня большие сомнения.
Если нам не помогут, то мы тоже никого не пощадим.
Re[10]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 25.09.17 16:21
Оценка:
Здравствуйте, IT, Вы писали:

Doc>>Где я такое сказал? А из твоих слов можно подумать что есть только один способ получения заданного результата

IT>Вообще-то, да.

Странно такое слышать. Ну скажем, надо удалить/обновить записи по условию. Можно написать
1) Выбрать Id по условию и удалить по списку Id
2) Удалить по условию

Причем EF идет по первому.
Re[11]: В сотый раз про сущности EF и бизнес-объекты...
От: IT Россия linq2db.com
Дата: 25.09.17 17:18
Оценка:
Здравствуйте, Doc, Вы писали:

Doc>Странно такое слышать. Ну скажем, надо удалить/обновить записи по условию. Можно написать


Это понятно. С изменением данных у EF всё плохо с рождения. Я подумал, что EF косячит при построении SELECT запросов.
Если нам не помогут, то мы тоже никого не пощадим.
Re[12]: В сотый раз про сущности EF и бизнес-объекты...
От: Doc Россия http://andrey.moveax.ru
Дата: 26.09.17 05:05
Оценка:
Здравствуйте, IT, Вы писали:

Doc>>Странно такое слышать. Ну скажем, надо удалить/обновить записи по условию. Можно написать

IT>Это понятно. С изменением данных у EF всё плохо с рождения. Я подумал, что EF косячит при построении SELECT запросов.

Дали же пример про left join
http://rsdn.org/forum/flame.comp/5670024.1
Автор: IB
Дата: 01.07.14
Re[9]: В сотый раз про сущности EF и бизнес-объекты...
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 26.09.17 06:41
Оценка:
Здравствуйте, IB, Вы писали:

IB>Да. Ему нужны еще дополнительные метаданные для каких-то своих внутренних нужд и для этого он лепит дополнительные подзапросы.


Там еще есть выборка таймстампа, чтобы потом ConcurrencyException выкидывать при коллизиях, вызванных, опять же, идеей накапливать изменения в памяти перед сбросом в БД.
... << RSDN@Home 1.0.0 alpha 5 rev. 0 on Windows 8 6.2.9200.0>>
AVK Blog
Re[10]: В сотый раз про сущности EF и бизнес-объекты...
От: IB Австрия http://rsdn.ru
Дата: 26.09.17 09:23
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>Там еще есть выборка таймстампа, чтобы потом ConcurrencyException выкидывать при коллизиях, вызванных, опять же, идеей накапливать изменения в памяти перед сбросом в БД.

Ну да, он же больной с рождения, непонимаю почему им пользуются. То есть понимаю, конечно, но осуждаю. )
Мы уже победили, просто это еще не так заметно...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.