которые внутри используют OUTER APPLY
Вопрос планы запросов я посмотрю в понедельник, но может у кого то уже имеется опыт сравнения left join vs outer apply?
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> В Linq нет прямого left join , а так же соединение по неравенству S>Но в Linq можно использовать коррелирующие запросы http://rsdn.ru/forum/dotnet/6160765.flat
S>которые внутри используют OUTER APPLY S>Вопрос планы запросов я посмотрю в понедельник, но может у кого то уже имеется опыт сравнения left join vs outer apply?
Правильный ответ на вопрос можно получить только посмотрев план запроса, т.к. простой заменой одного выражения на другое не удастся создать логически эквивалентные запросы. Поэтому многое будет зависеть от реализации этих эквивалентов, плюс свое влияние окажет схема данных и сами данные как например в сравнении JOIN и CROSS APPLY
.
На базе AdventureWorks2008R2 я попытался написать два запроса с использованием left join и outer apply по аналогии с вашим SQL запросом:
/*1*/select *
from Sales.SalesOrderHeader h
left join
(
select top 1 with ties d1.SalesOrderID, d1.OrderQty
from Sales.SalesOrderDetail d1
order by row_number() over(partition by d1.SalesOrderID order by d1.OrderQty desc)
) d on h.SalesOrderID = d.SalesOrderID
/*2*/select *
from Sales.SalesOrderHeader h
outer apply
(
select top 1 d1.SalesOrderID, d1.OrderQty
from Sales.SalesOrderDetail d1
where d1.SalesOrderID = h.SalesOrderID
order by d1.OrderQty desc
) d
Результат:
Query 1: Query cost (relative to the batch): 3%
Query 2: Query cost (relative to the batch): 97%
Т.е. запрос с outer apply в моем случае показал себя совсем не с лучшей стороны.
O>[sql] O>/*1*/ O>select * O>from Sales.SalesOrderHeader h O>left join O>( O> select top 1 with ties d1.SalesOrderID, d1.OrderQty O> from Sales.SalesOrderDetail d1 O> order by row_number() over(partition by d1.SalesOrderID order by d1.OrderQty desc) O>) d on h.SalesOrderID = d.SalesOrderID
WITH TIES
Используется, если требуется вернуть две или более строки, которые совместно занимают последнее место в ограниченном результирующем наборе. Требуется использовать с предложением ORDER BY. WITH TIES может привести к тому, что вернется строк больше, чем указано в значении expression. Например, если expression имеет значение 5, но еще 2 строки соответствуют значениям в столбцах ORDER BY в строке 5, то результирующий набор будет содержать 7 строк.
Предложение TOP...WITH TIES может быть задано только в инструкциях SELECT, и только если указано предложение ORDER BY. Порядок возврата связанных записей произволен. ORDER BY не влияет на это правило.
Понял вернет все записи по 1 row_number()
Спасибо не знал.
Кстати интересно если SalesOrderDetail загрузить в темповую таблицу, проиндексировать, а затем выполнить к ней запрс
select *
from Sales.SalesOrderHeader h
outer apply
(
select top 1 d1.SalesOrderID, d1.OrderQty
from #TempSalesOrderDetail d1
where d1.SalesOrderID = h.SalesOrderID
order by d1.OrderQty desc
) d
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Serginio1, Вы писали:
S>> В Linq нет ... соединение по неравенству
IT>Попробуй
IT>
IT>from t1 in Table1
IT>from t2 in Table2.Where(t => t.Field1 != t1.Field2)
IT>...
IT>
Большое спасибо!
Прошу прощения имел ввиду левое соединение.
Хотя можно объединить два запроса
query=from t1 in Table1
from t2 in Table2.Where(t => t.Field1 != t1.Field2)
Select t1,t2
query=from t1 in Table1
join item in query
on t1.Key equals item.t1.Key into outer
from itemO in outer.DefaultIfEmpty()
select new {t1, item.t2};
и солнце б утром не вставало, когда бы не было меня
GROUP JOIN
Whene a join clause use an INTO expression, then it is called a group join. A group join produces a sequence of object arrays based on properties equivalence of left collection and right collection. If right collection has no matching elements with left collection then an empty array will be produced.
C# Code
var q=(from pd in dataContext.tblProducts
join od in dataContext.tblOrders on
pd.ProductID equals od.ProductID into t orderby pd.ProductID
select new
{
pd.ProductID,
pd.Name,
pd.UnitPrice,
Order=t
}).ToList();
Генерится левое соединение.
и солнце б утром не вставало, когда бы не было меня
Прямого аналога GroupJoin в SQL нет. Для получения аналога нужно генерировать либо избыточный запрос, либо несколько запросов.
S>Генерится левое соединение.
Поэтому в сгенерированном коде может быть всё, что угодно и меняться от версии к версии LINQ провайдера.
Если нам не помогут, то мы тоже никого не пощадим.
Вот какие левые запросы с условием на неравенство получились
var бд = Константы1С.ГлобальныйКонтекст.БД;
var qr = from Номенклатура in бд.Спр_Номенклатура
from единицы in бд.Спр_Единицы.Where(единица => единица.ВладелецId == Номенклатура.ID && единица.ШтрихКод.CompareTo("4") > 0).DefaultIfEmpty()
select new { Номенклатура.Наименование,
Номенклатура.ПолнНаименование,
единицы.ШтрихКод,
ОКЕИ=единицы.ОКЕИ.Наименование
};
foreach (var элем in qr.Take(1000))
{
if (элем.ШтрихКод == null)
continue;
Console.WriteLine("{0}.{1} - {2}", элем.Наименование.TrimEnd(), элем.ШтрихКод == null ? "null" : элем.ШтрихКод, элем.ПолнНаименование.TrimEnd(), элем.ОКЕИ == null ? "null" : элем.ОКЕИ);
}
Выдает такой запрос
SELECT
[Limit1].[C1] AS [C1],
[Limit1].[DESCR] AS [DESCR],
[Limit1].[SP101] AS [SP101],
[Limit1].[SP80] AS [SP80],
[Limit1].[DESCR1] AS [DESCR1]
FROM ( SELECT TOP (1000)
[Extent1].[DESCR] AS [DESCR],
[Extent1].[SP101] AS [SP101],
[Extent2].[SP80] AS [SP80],
[Extent3].[DESCR] AS [DESCR1],
1 AS [C1]
FROM [dbo].[SC84] AS [Extent1]
LEFT OUTER JOIN [dbo].[SC75] AS [Extent2] ON ([Extent2].[PARENTEXT] = [Extent1].[ID]) AND ([Extent2].[SP80] > N'4')
LEFT OUTER JOIN [dbo].[SC41] AS [Extent3] ON [Extent2].[SP79] = [Extent3].[ID]
) AS [Limit1]
Или больше мне нравится таой запрос
var бд = Константы1С.ГлобальныйКонтекст.БД;
var qr = from Номенклатура in бд.Спр_Номенклатура
select new
{
Номенклатура.Наименование,
Номенклатура.ПолнНаименование,
Единицы = (Номенклатура.ПодчиненныеЕдиницы.Where(единица => единица.ШтрихКод.CompareTo("4") > 0)
.Select(единица =>
new
{
единица.ШтрихКод,
ОКЕИ = единица.ОКЕИ.Наименование
}
)
)
};
foreach (var элем in qr.Take(1000))
{
foreach (var единица in элем.Единицы)
Console.WriteLine("{0}.{1} - {2}", элем.Наименование.TrimEnd(), единица.ШтрихКод, элем.ПолнНаименование.TrimEnd(), единица.ОКЕИ);
}
Генерирут SQL запрос
SELECT
[Project2].[ID] AS [ID],
[Project2].[C1] AS [C1],
[Project2].[DESCR] AS [DESCR],
[Project2].[SP101] AS [SP101],
[Project2].[C2] AS [C2],
[Project2].[SP80] AS [SP80],
[Project2].[DESCR1] AS [DESCR1]
FROM ( SELECT
[Limit1].[ID] AS [ID],
[Limit1].[DESCR] AS [DESCR],
[Limit1].[SP101] AS [SP101],
[Limit1].[C1] AS [C1],
[Join1].[SP80] AS [SP80],
[Join1].[DESCR] AS [DESCR1],
CASE WHEN ([Join1].[PARENTEXT] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2]
FROM (SELECT TOP (1000)
[Extent1].[ID] AS [ID],
[Extent1].[DESCR] AS [DESCR],
[Extent1].[SP101] AS [SP101],
1 AS [C1]
FROM [dbo].[SC84] AS [Extent1] ) AS [Limit1]
LEFT OUTER JOIN (SELECT [Extent2].[PARENTEXT] AS [PARENTEXT], [Extent2].[SP80] AS [SP80], [Extent3].[DESCR] AS [DESCR]
FROM [dbo].[SC75] AS [Extent2]
INNER JOIN [dbo].[SC41] AS [Extent3] ON [Extent2].[SP79] = [Extent3].[ID] ) AS [Join1] ON ([Limit1].[ID] = [Join1].[PARENTEXT]) AND ([Join1].[SP80] > N'4')
) AS [Project2]
ORDER BY [Project2].[ID] ASC, [Project2].[C2] ASC
и солнце б утром не вставало, когда бы не было меня
Re: Code First и Linq to EF на примере 1С версии 7.7
var Запрос = qr.CreateQuery<Справочник.Номенклатура>("Select p From Спр_Номенклатура as p");
foreach (var элем in Запрос)
{
Console.WriteLine("{0}.{1} - {2}", элем.Наименование.TrimEnd(), элем.Артикул, элем.ПолнНаименование.TrimEnd());
}
Вот такую ошибку выдает
CreateQuery Простой идентификатор "Спр_Номенклатура" должен содержать только основные символы латиницы.
Для символов UNICODE следует использовать экранированный идентификатор
и солнце б утром не вставало, когда бы не было меня
Re[2]: Code First и Linq to EF на примере 1С версии 7.7
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>
S>var Запрос = qr.CreateQuery<Справочник.Номенклатура>("Select p From Спр_Номенклатура as p");
S> foreach (var элем in Запрос)
S> {
S> Console.WriteLine("{0}.{1} - {2}", элем.Наименование.TrimEnd(), элем.Артикул, элем.ПолнНаименование.TrimEnd());
S> }
S>
S>Вот такую ошибку выдает
S>
S>CreateQuery Простой идентификатор "Спр_Номенклатура" должен содержать только основные символы латиницы.
S>Для символов UNICODE следует использовать экранированный идентификатор
Попробовал перекодировать в символы Юникоде
public string ПерекодироватьЮникоде(string Запрос)
{
var sb = new StringBuilder();
foreach (var слово in Запрос)
{
if (((int)слово) < 128)
sb.Append(слово);
else
sb.AppendFormat(@"\u{0}", ((int)слово).ToString("X4"));
}
Ругается "Недопустимый синтаксис запроса., строка 1, столбец 15
Строка такая
Select p From \u0421\u043F\u0440_\u041D\u043E\u043C\u0435\u043D\u043A\u043B\u0430\u0442\u0443\u0440\u0430 as p
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Большое спасибо. Кстати вот работая с 1С совсем от жизни отстал. Например мне 1 часть твоего ответа S>в http://rsdn.ru/forum/db/6043892.flat
S>WITH TIES
S>Используется, если требуется вернуть две или более строки, которые совместно занимают последнее место в ограниченном результирующем наборе. Требуется использовать с предложением ORDER BY. WITH TIES может привести к тому, что вернется строк больше, чем указано в значении expression. Например, если expression имеет значение 5, но еще 2 строки соответствуют значениям в столбцах ORDER BY в строке 5, то результирующий набор будет содержать 7 строк.
S>Предложение TOP...WITH TIES может быть задано только в инструкциях SELECT, и только если указано предложение ORDER BY. Порядок возврата связанных записей произволен. ORDER BY не влияет на это правило.
S> Понял вернет все записи по 1 row_number() S>Спасибо не знал.
Все верно. Конструкция вида select top 1 with ties ... from ... order by row_number() over(partition by ... order by ...) позволяет извлечь для каждого раздела (partition) по одной записи. Причем, какая именно запись попадет в выборку, определяется порядком сортировки в оконной функции row_number()
S>А как например по top (3)
Что касается top n with ties, где n > 0 и в случае использования выражения сортировки отличного от оконной функции, то можно рассмотреть пример, где первый запрос – непосредственное использование top with ties, а второй запрос – альтернативная реализация. Фактически top n with ties сводится к упорядочению данных по выражению/полю указанному в order by и выбору ВСЕХ значений, совпадающих с первыми n записями выражения/поля сортировки.
declare @n int = 1
if object_id('tempdb..#t') is not null
drop table #t
create table #t(n int)
insert into #t
select 1 as n union all
select 1 union all
select 1 union all
select 1 union all
select 2 union all
select 2 union all
select 2 union all
select 3 union all
select 3
-- Запрос с top with tiesselect top(@n) with ties *
from #t
order by n desc-- Замена запроса с top with tiesselect *
from #t
where n in (select top(@n) n from #t order by n desc)
order by n desc
Для @n in (1,2) вернутся значения 3,3
Для @n in (3,4,5) вернутся 3,3,2,2,2
Для @n in (6,7,8,9) вернутся значения 3,3,2,2,2,1,1,1,1
Здравствуйте, Serginio1, Вы писали:
S> Кстати меня даже больше интересует именно как будет отображаться линковский запрос например при условии неравенства S>Например S>
S>from a in aa
S> select new (a=a, b=(
S> select b from bb where a.id=b.id && a.Price<b.price
S> select b)
S>)
S>
Запрос можно конечно посмотреть через LinqPad, но как правильно здесь уже заметили, реализация может меняться при смене Linq провайдера.
Здравствуйте, Olaf, Вы писали:
O>Здравствуйте, Serginio1, Вы писали:
S>> Кстати меня даже больше интересует именно как будет отображаться линковский запрос например при условии неравенства S>>Например S>>
S>>from a in aa
S>> select new (a=a, b=(
S>> select b from bb where a.id=b.id && a.Price<b.price
S>> select b)
S>>)
S>>
O>Запрос можно конечно посмотреть через LinqPad, но как правильно здесь уже заметили, реализация может меняться при смене Linq провайдера.
select *
from
(
select mh.*, row_number() over(partition by mh.Mess_ID order by mh.Date desc, mh.Time desc) as n
from dbo.MessageHists mh
where mh.Founder_date < @StartDate
) a
where a.n <= n
Это близкий аналог с tier
и солнце б утром не вставало, когда бы не было меня
Re: Code First и Linq to EF на примере 1С версии 7.7
S> Например хотел прикрутить CreateQuery. Вернее прикрутил, и действительно можно использовать псевдонимы таблиц и полей, но проблема была с Юникодом. S>И решил не заморачиваться. S> Буду благодарен, на полезные ссылки и мнения.
Прикрутил. Вот таким образом
var str = @"Select p.[Наименование],p.[Код],p.[ПолнНаименование] From [Спр_Номенклатура] as p";
var Запрос = qr.CreateQuery<dynamic>(str );
Интересно работает он с temporary Table?
и солнце б утром не вставало, когда бы не было меня
Re[2]: Code First и Linq to EF на примере 1С версии 7.7
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>> Например хотел прикрутить CreateQuery. Вернее прикрутил, и действительно можно использовать псевдонимы таблиц и полей, но проблема была с Юникодом. S>>И решил не заморачиваться. S>> Буду благодарен, на полезные ссылки и мнения. S> Прикрутил. Вот таким образом
S>
S>var str = @"Select p.[Наименование],p.[Код],p.[ПолнНаименование] From [Спр_Номенклатура] as p";
S> var Запрос = qr.CreateQuery<dynamic>(str );
S>
S> Интересно работает он с temporary Table?
К сожалению нет
Идентификаторы
В языке Transact-SQL сравнение идентификаторов всегда осуществляется с учетом параметров сортировки текущей базы данных. В Entity SQL идентификаторы всегда чувствительны к регистру и диакритическим знакам (то есть Entity SQL различает диакритические знаки, например «а» отличается от «ấ»). Entity SQL обрабатывает версии букв, которые кажутся такими же, но являются другими символами и происходят из других кодовых страниц. Для получения дополнительной информации см. Набор символов ввода (Entity SQL).
Функциональность Transact-SQL, недоступная в Entity SQL
Следующая функциональность Transact-SQL недоступна в языке Entity SQL.
DML
В настоящее время язык Entity SQL не поддерживает инструкции DML (вставка, обновление, удаление).
DDL
Текущая версия Entity SQL не поддерживает DDL.
Командное программирование
Язык Entity SQL не поддерживает командное программирование в отличие от Transact-SQL. Используйте вместо этого языки программирования.
Функции группирования
Язык Entity SQL пока не поддерживает функции группирования (например, CUBE, ROLLUP и GROUPING_SET).
Функции аналитики
Язык Entity SQL не предоставляет (пока) поддержку функций аналитики.
Встроенные функции, операторы
Язык Entity SQL поддерживает подмножество встроенных функций и операторов Transact-SQL. Вероятно, эти операторы и функции будут реализованы ведущими поставщиками хранилищ. В языке Entity SQL используются специальные функции для хранилищ, объявленные в манифесте поставщика. Кроме того, модель Entity Framework позволяет объявлять встроенные и пользовательские функции хранилища для использования в Entity SQL.
Подсказки
Язык Entity SQL не предоставляет механизм подсказок в запросах.
Пакетирование результатов запроса
Entity SQL не поддерживает пакетирование результатов запросов. Например, допустим следующий запрос Transact-SQL (отправляемый как пакет):
select * from products;
select * from catagories;
Однако эквивалент Entity SQL не поддерживается.
Select value p from Products as p;
Select value c from Categories as c;
Entity SQL поддерживает только запросы, которые выдают один результат на одну команду.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Выдает такой запрос S>
S>SELECT
S> [Limit1].[C1] AS [C1],
S> [Limit1].[DESCR] AS [DESCR],
S> [Limit1].[SP101] AS [SP101],
S> [Limit1].[SP80] AS [SP80],
S> [Limit1].[DESCR1] AS [DESCR1]
S> FROM ( SELECT TOP (1000)
S> [Extent1].[DESCR] AS [DESCR],
S> [Extent1].[SP101] AS [SP101],
S> [Extent2].[SP80] AS [SP80],
S> [Extent3].[DESCR] AS [DESCR1],
S> 1 AS [C1]
S> FROM [dbo].[SC84] AS [Extent1]
S> LEFT OUTER JOIN [dbo].[SC75] AS [Extent2] ON ([Extent2].[PARENTEXT] = [Extent1].[ID]) AND ([Extent2].[SP80] > N'4')
S> LEFT OUTER JOIN [dbo].[SC41] AS [Extent3] ON [Extent2].[SP79] = [Extent3].[ID]
S> ) AS [Limit1]
S>
Какой кашмар. linq2db на это генерирует примерно следующее:
SELECT TOP (1000)
[t2].[ChildID],
[t2].[ParentID],
[t1].[GrandChildID]
FROM
[Child] [t2]
LEFT JOIN [GrandChild] [t1] ON [t1].[ChildID] = [t2].[ChildID] AND [t1].[GrandChildID] > 0
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Serginio1, Вы писали:
S>>Выдает такой запрос S>>
S>>SELECT
S>> [Limit1].[C1] AS [C1],
S>> [Limit1].[DESCR] AS [DESCR],
S>> [Limit1].[SP101] AS [SP101],
S>> [Limit1].[SP80] AS [SP80],
S>> [Limit1].[DESCR1] AS [DESCR1]
S>> FROM ( SELECT TOP (1000)
S>> [Extent1].[DESCR] AS [DESCR],
S>> [Extent1].[SP101] AS [SP101],
S>> [Extent2].[SP80] AS [SP80],
S>> [Extent3].[DESCR] AS [DESCR1],
S>> 1 AS [C1]
S>> FROM [dbo].[SC84] AS [Extent1]
S>> LEFT OUTER JOIN [dbo].[SC75] AS [Extent2] ON ([Extent2].[PARENTEXT] = [Extent1].[ID]) AND ([Extent2].[SP80] > N'4')
S>> LEFT OUTER JOIN [dbo].[SC41] AS [Extent3] ON [Extent2].[SP79] = [Extent3].[ID]
S>> ) AS [Limit1]
S>>
IT>Какой кашмар. linq2db на это генерирует примерно следующее:
IT>
IT>SELECT TOP (1000)
IT> [t2].[ChildID],
IT> [t2].[ParentID],
IT> [t1].[GrandChildID]
IT>FROM
IT> [Child] [t2]
IT> LEFT JOIN [GrandChild] [t1] ON [t1].[ChildID] = [t2].[ChildID] AND [t1].[GrandChildID] > 0
IT>
Ну реальный то запрос немного другой
Там есть еще одно соединение
бд = Константы1С.ГлобальныйКонтекст.БД;
var qr = from Номенклатура in бд.Спр_Номенклатура
select new
{
Номенклатура.Наименование,
Номенклатура.ПолнНаименование,
Единицы = (Номенклатура.ПодчиненныеЕдиницы.Where(единица => единица.ШтрихКод.CompareTo("4") > 0)
.Select(единица =>
new
{
единица.ШтрихКод,
ОКЕИ = единица.ОКЕИ.Наименование
}
)
)
};
ОКЕИ это тип Справочник.ОКЕИ.
А основной запрос это просто обычно приведение к нужному типу и служебным полям для маппирования запроса на модель.
Мы в итоге получам Лис листов
foreach (var элем in qr.Take(1000))
{
// Пропускаем данные по но номенклатуре и печатаем только те у которых есть подчиненные единицы со штрих кодом >"4"
foreach (var единица in элем.Единицы)
Console.WriteLine("{0}.{1} — {2}", элем.Наименование.TrimEnd(), единица.ШтрихКод, элем.ПолнНаименование.TrimEnd(), единица.ОКЕИ);
}
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S>Там есть еще одно соединение
Сразу не заметил:
SELECT TOP (1000)
[t3].[ChildID],
[t3].[ParentID],
[t1].[GrandChildID],
[t2].[Value1]
FROM
[Child] [t3]
LEFT JOIN [GrandChild] [t1] ON [t1].[ChildID] = [t3].[ChildID] AND [t1].[GrandChildID] > 0
LEFT JOIN [Parent] [t2] ON [t3].[ParentID] = [t2].[ParentID]
Если нам не помогут, то мы тоже никого не пощадим.
Здравствуйте, IT, Вы писали:
IT>Здравствуйте, Serginio1, Вы писали:
S>>Там есть еще одно соединение
IT>Сразу не заметил:
IT>
IT>SELECT TOP (1000)
IT> [t3].[ChildID],
IT> [t3].[ParentID],
IT> [t1].[GrandChildID],
IT> [t2].[Value1]
IT>FROM
IT> [Child] [t3]
IT> LEFT JOIN [GrandChild] [t1] ON [t1].[ChildID] = [t3].[ChildID] AND [t1].[GrandChildID] > 0
IT> LEFT JOIN [Parent] [t2] ON [t3].[ParentID] = [t2].[ParentID]
IT>
Ну они ничем не отличаюся, кроме дополнительного привиедения полей.
Вот интересней запрос
А вот такой
var qr = (from единица in бд.Спр_Единицы
group единица by new {
единица.ВладелецId,
Наименование=единица.Владелец.Наименование.TrimEnd()
}
into группа
let Количество = группа.Count()
where Количество > 1
select new
{
Наименование = группа.Key.Наименование,
Количество = Количество,
Группа = группа
});
foreach (var элем in qr)
{
Console.WriteLine("{0}.{1} - ", элем.Наименование, элем.Количество);
foreach (var единица in элем.Группа)
{
Console.WriteLine("{0}.{1} - ", единица.ОКЕИ.Наименование, единица.ШтрихКод);
}
}
Превращается
SELECT
[Project1].[C2] AS [C1],
[Project1].[C3] AS [C2],
[Project1].[C1] AS [C3],
[Project1].[PARENTEXT] AS [PARENTEXT],
[Project1].[C4] AS [C4],
[Project1].[ID] AS [ID],
[Project1].[PARENTEXT1] AS [PARENTEXT1],
[Project1].[ISMARK] AS [ISMARK],
[Project1].[SP79] AS [SP79],
[Project1].[SP76] AS [SP76],
[Project1].[SP78] AS [SP78],
[Project1].[SP80] AS [SP80],
[Project1].[SP8752] AS [SP8752],
[Project1].[SP9519] AS [SP9519]
FROM ( SELECT
[GroupBy1].[A1] AS [C1],
[GroupBy1].[K1] AS [PARENTEXT],
[GroupBy1].[K2] AS [C2],
[GroupBy1].[K3] AS [C3],
[Join2].[ID1] AS [ID],
[Join2].[PARENTEXT] AS [PARENTEXT1],
[Join2].[ISMARK1] AS [ISMARK],
[Join2].[SP79] AS [SP79],
[Join2].[SP76] AS [SP76],
[Join2].[SP78] AS [SP78],
[Join2].[SP80] AS [SP80],
[Join2].[SP8752] AS [SP8752],
[Join2].[SP9519] AS [SP9519],
CASE WHEN ([Join2].[ID1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C4]
FROM (SELECT
[Join1].[K1] AS [K1],
[Join1].[K2] AS [K2],
[Join1].[K3] AS [K3],
COUNT([Join1].[A1]) AS [A1]
FROM ( SELECT
[Extent1].[PARENTEXT] AS [K1],
1 AS [K2],
RTRIM([Extent2].[DESCR]) AS [K3],
1 AS [A1]
FROM [dbo].[SC75] AS [Extent1]
INNER JOIN [dbo].[SC84] AS [Extent2] ON [Extent1].[PARENTEXT] = [Extent2].[ID]
) AS [Join1]
GROUP BY [K1], [K2], [K3] ) AS [GroupBy1]
LEFT OUTER JOIN (SELECT [Extent3].[ID] AS [ID1], [Extent3].[PARENTEXT] AS [PARENTEXT], [Extent3].[ISMARK] AS [ISMARK1], [Extent3].[SP79] AS [SP79], [Extent3].[SP76] AS [SP76], [Extent3].[SP78] AS [SP78], [Extent3].[SP80] AS [SP80], [Extent3].[SP8752] AS [SP8752], [Extent3].[SP9519] AS [SP9519], [Extent4].[DESCR] AS [DESCR]
FROM [dbo].[SC75] AS [Extent3]
INNER JOIN [dbo].[SC84] AS [Extent4] ON [Extent3].[PARENTEXT] = [Extent4].[ID] ) AS [Join2] ON ([GroupBy1].[K1] = [Join2].[PARENTEXT]) AND (([GroupBy1].[K3] = (RTRIM([Join2].[DESCR]))) OR (([GroupBy1].[K3] IS NULL) AND (RTRIM([Join2].[DESCR]) IS NULL)))
WHERE [GroupBy1].[A1] > 1
) AS [Project1]
ORDER BY [Project1].[C2] ASC, [Project1].[PARENTEXT] ASC, [Project1].[C3] ASC, [Project1].[C4] ASC
Но выполняется быстро
и солнце б утром не вставало, когда бы не было меня
Обновил файлы. Наткнулся на забавную вещь.
В 1С Есть свойства неопределенного типа которое состоит из нескольких полей. В Code Firs есть атрибут ComplexType
public partial class Тестовый : СправочникПредок
{
public partial class НеопределенныеТипы
{
[ComplexType]
public class ЛюбаяСсылка_Fld19 : НеопределенныйТип, НеопределенныйТипСсылочный
{
[Column("_Fld19_TYPE")]
[Required]
[MaxLength(1)]
override public byte[] Тип { get; set; }
[Column("_Fld19_RTREF")]
[Required]
[MaxLength(4)]
public byte[] НомерТаблицы { get; set; }
[Column("_Fld19_RRREF")]
[Required]
[MaxLength(16)]
public byte[] Ссылка { get; set; }
}
}
}
public partial class Тестовый : СправочникПредок
{
public partial class ТЧ
{
public partial class НеопределенныеТипы
{
[ComplexType]
public class ЛюбаяСсылка_Fld52 : НеопределенныйТип, НеопределенныйТипСсылочный
{
[Column("_Fld52_TYPE")]
[Required]
[MaxLength(1)]
override public byte[] Тип { get; set; }
[Column("_Fld52_RTREF")]
[Required]
[MaxLength(4)]
public byte[] НомерТаблицы { get; set; }
[Column("_Fld52_RRREF")]
[Required]
[MaxLength(16)]
public byte[] Ссылка { get; set; }
}
}
}
}
Есть поле в разных типах ЛюбаяСсылка, но в базе все названия [ComplexType] должны быть уникальными.
Поэтому добавляю номер таблицы для неопределенных владельцев и номер поля для неопределенных полей
и солнце б утром не вставало, когда бы не было меня
Кстати посмотрел на просторах интернета, что то не нашел описания подключения к ODATA.
На той тестовой конфигурации опубликовал ODATA
Установил справочники
Массив = Новый Массив();
Для Каждого Справочник Из Метаданные.Справочники Цикл
Массив.Добавить(Справочник);
КонецЦикла;
УстановитьСоставСтандартногоИнтерфейсаOData(Массив);
var uriString = @"http://localhost/LinqBD/odata/standard.odata/";;
var context = new ServiceReference1.EnterpriseV8(new Uri(uriString));
var query = context.CreateQuery<ServiceReference1.Catalog_Тестовый>("Catalog_Тестовый");
var result = query.ToList();
и солнце б утром не вставало, когда бы не было меня
Re[2]: Code First и Linq to EF на примере 1С версии 7.7 и 8.
Здравствуйте, Serginio1, Вы писали:
S>Кстати посмотрел на просторах интернета, что то не нашел описания подключения к ODATA.
Так же есть поддержка JSON
var uriString = @"http://localhost/LinqBD/odata/standard.odata/";
var context = new ServiceReference1.EnterpriseV8(new Uri(uriString));
context.Format.UseJson();
var query = context.CreateQuery<ServiceReference1.Catalog_Тестовый>(@"Catalog_Тестовый");
var result = query.ToList();
Генерирует такой запрос
GET http://localhost/LinqBD/odata/standard.odata/Catalog_%D0%A2%D0%B5%D1%81%D1%82%D0%BE%D0%B2%D1%8B%D0%B9 HTTP/1.1
DataServiceVersion: 1.0;NetFx
MaxDataServiceVersion: 3.0;NetFx
Accept: application/json;odata=minimalmetadata
Accept-Charset: UTF-8
User-Agent: Microsoft ADO.NET Data Services
Host: tc-smirnov-s
Connection: Keep-Alive
Здравствуйте, Serginio1, Вы писали:
S>Здравствуйте, Serginio1, Вы писали:
S>>Кстати посмотрел на просторах интернета, что то не нашел описания подключения к ODATA. S>Так же есть поддержка JSON
S>
S>var uriString = @"http://localhost/LinqBD/odata/standard.odata/";
S> var context = new ServiceReference1.EnterpriseV8(new Uri(uriString));
S> context.Format.UseJson();
S> var query = context.CreateQuery<ServiceReference1.Catalog_Тестовый>(@"Catalog_Тестовый");
S> var result = query.ToList();
S>
S>Можно применять фильтры
S>
S> var query = context.CreateQuery<ServiceReference1.Catalog_Тестовый>(@"Catalog_Тестовый")
S> .AddQueryOption("$filter", "Число le 100");
S>
А можно и так
var result = (from Тестовый in context.Catalog_Тестовый
where Тестовый.Число<500
select Тестовый).ToList();
и солнце б утром не вставало, когда бы не было меня
Re[4]: Code First и Linq to EF на примере 1С версии 7.7 и 8.
Динамическая компиляция класса обертки для использования .Net событий в 1С через ДобавитьОбработчик или ОбработкаВнешнегоСобытия, а так же генерация модулей на C# и 1С для подключения к событиям. Использование DynamicMethod и ILGenerator. Представлены примеры на использовании событий System.IO.FileSystemWatcher (Ожидает уведомления файловой системы об изменениях и инициирует события при изменениях каталога или файла в каталоге.) и SerialPort (обработка сканера штрих кода подключенного к COM порту). Обертка позволяет использовать сборки .Net только на языке 1С.
Эта статья является дополнением разработки Использование сборок .NET в 1С 7.x b 8.x находящейся здесь http://infostart.ru/public/238584/
и солнце б утром не вставало, когда бы не было меня