Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / как сделать ID. LIKE / 25 сообщений из 30, страница 1 из 2
11.01.2013, 18:59
    #38106950
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Сижу туплю. Нужен обычный запрос
Код: c#
1.
Table.ID Like ('111%')

ToString() говорит, что linq2entities не знает. Как быть-то?!
...
Рейтинг: 0 / 0
11.01.2013, 20:00
    #38107004
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivan,

Не спрашивая зачем это надо... Это только поймет EF provider для ms sql.

Способ 1 (так и не заработал из-за пробелов, хз как побороть)

Код: c#
1.
2.
3.
4.
5.
6.
using System.Data.Objects.SqlClient;
...
                var z = from a in ctx.ANIMAL
                        where SqlFunctions.StringConvert((decimal?)a.ID_ANIMAL).StartsWith("111")
                        select a;
...



Код: sql
1.
2.
3.
4.
5.
SELECT 
[Extent1].[ID_ANIMAL] AS [ID_ANIMAL], 
[Extent1].[NAME] AS [NAME]
FROM [dbo].[ANIMAL] AS [Extent1]
WHERE STR( CAST( [Extent1].[ID_ANIMAL] AS decimal(19,0))) LIKE N'111%'



Способ 2 (заработал как надо)

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
USE [DB1]
GO
/****** Object:  UserDefinedFunction [dbo].[GetTotalAmount]    Script Date: 01/11/2013 19:42:14 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER FUNCTION [dbo].[GetTotalAmount]
(@num as int)
RETURNS nvarchar
AS
BEGIN
return cast(@num as nvarchar)
END




Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    public partial class DB1Entities1
    {
        [EdmFunction("DB1Model.Store", "ConvertToStr")]
        public static string GetTotalAmount(Nullable<int> num)
        {
            throw new NotImplementedException("Cannot invoke this method");
        }
    }

...

                var z = from a in ctx.ANIMAL
                        where DB1Entities1.GetTotalAmount(a.ID_ANIMAL).StartsWith("1")
                        select a;



Код: c#
1.
2.
3.
4.
5.
SELECT 
[Extent1].[ID_ANIMAL] AS [ID_ANIMAL], 
[Extent1].[NAME] AS [NAME]
FROM [dbo].[ANIMAL] AS [Extent1]
WHERE [dbo].[ConvertToStr]([Extent1].[ID_ANIMAL]) LIKE N'1%'



Можно еще через UDF, позже запилю...
...
Рейтинг: 0 / 0
11.01.2013, 21:23
    #38107065
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Способ 3 (не создавая ничего в БД)

в csdl в пределах узла Scheme запиливаем следующий кусок:

Код: sql
1.
2.
3.
4.
5.
6.
        <Function Name="ConvertToStringUDF" ReturnType="String">
          <Parameter Name="num" Type="Edm.Int32" />
          <DefiningExpression>
            CAST(num AS Edm.String)
          </DefiningExpression>
        </Function>



Делаешь такой вот STUB:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
    public partial class DB1Entities1
    {
        [EdmFunction("DB1Model", "ConvertToStringUDF")]
        public static string GetTotalAmount(Nullable<int> num)
        {
            throw new NotImplementedException("Cannot invoke this method");
        }
    }



Запрос LINQ TO ENTITY

Код: sql
1.
2.
3.
                var z = from a in ctx.ANIMAL
                        where DB1Entities1.GetTotalAmount(a.ID_ANIMAL).StartsWith("1")
                        select a;



Код: sql
1.
2.
3.
4.
5.
SELECT 
[Extent1].[ID_ANIMAL] AS [ID_ANIMAL], 
[Extent1].[NAME] AS [NAME]
FROM [dbo].[ANIMAL] AS [Extent1]
WHERE  CAST( [Extent1].[ID_ANIMAL] AS nvarchar(max)) LIKE N'1%'



PROFIT! Да изапрос вроде не такое уж и УГ.
...
Рейтинг: 0 / 0
11.01.2013, 21:29
    #38107069
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
GetTotalAmount заменить на ConvertToStringUDF. на работоспособность не влияет но в заблуждение вводит. :)
...
Рейтинг: 0 / 0
11.01.2013, 21:37
    #38107086
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Последнее (3 способ) может работать, теоретически, и на других EF провайдерах.
...
Рейтинг: 0 / 0
12.01.2013, 11:25
    #38107402
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivanСижу туплю. Нужен обычный запрос
Код: c#
1.
Table.ID Like ('111%')

ToString() говорит, что linq2entities не знает. Как быть-то?!
Для работы с деревьями, что-ли?
...
Рейтинг: 0 / 0
14.01.2013, 10:50
    #38108858
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУ,

нет, все тривиально. Делать автозаполнение по первым введенным цифрам. Не думал,что такой просто запрос будет такой гемор!
...
Рейтинг: 0 / 0
14.01.2013, 11:22
    #38108906
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
решение нашел:
Код: c#
1.
 w => SqlFunctions.StringConvert((decimal)w.ID).Trim().StartsWith(term)


w.ID - int, term - строка.
В MSSQL передается типа того:
Код: sql
1.
 where rtrim(ltrim(STR( CAST( ID AS decimal(19,0))))) LIKE N'808%'
...
Рейтинг: 0 / 0
14.01.2013, 11:58
    #38108965
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivanрешение нашел
За такие планы выполнения запроса тебя DBA кастрирует... :(
...
Рейтинг: 0 / 0
14.01.2013, 12:09
    #38108985
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУ,

сам бы себя кастрировал, но жалко. =) Думаю кэш немного спасет.
...
Рейтинг: 0 / 0
14.01.2013, 12:31
    #38109021
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivan,

если есть в MS SQL аналог Oracle function based index, можно с планом выкрутиться. но вставка медленнее станет.

можно колонку завести id_str, проиндексировать.
...
Рейтинг: 0 / 0
14.01.2013, 12:37
    #38109034
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Я в таких случаях поступаю очень просто: в DAL (или что там у нас) тупо пишу динамику и по сразу месту типизируюсь в класс. Никаких левых костылей в базе, хорошая производительность, всё спрятано от глаз. Быстро и просто.
...
Рейтинг: 0 / 0
14.01.2013, 13:47
    #38109168
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivanрешение нашел:
Код: c#
1.
 w => SqlFunctions.StringConvert((decimal)w.ID).Trim().StartsWith(term)


w.ID - int, term - строка.
В MSSQL передается типа того:
Код: sql
1.
 where rtrim(ltrim(STR( CAST( ID AS decimal(19,0))))) LIKE N'808%'



Хозяин - барин, но я бы выбрал третий способ (через UDF), честно говоря. Мне его запрос больше нравится. Если таблица большая и хочешь повысить скорость выборок, при твоем выборе можно поступить так

пример
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
CREATE TABLE [dbo].[T2](
	[ID] [int] IDENTITY(1,1) NOT NULL,

	/* функция должна совпадать с тем, что у тебя генерит ORM */
	[ID_STR]  AS (rtrim(ltrim(str(CONVERT([decimal](19,0),[ID],(0)))))) PERSISTED, 

	[ZZZ] [nvarchar](max) NULL,
 CONSTRAINT [PK_T2] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

/* забиваем достаточно данных, чтобы CBO считал нужным использовать индекс */
INSERT INTO T2(ZZZ)
	SELECT A.NAME
	  FROM SYSOBJECTS A
				CROSS JOIN
		   SYSOBJECTS B;
GO

/* индекс на COMPUTED колонку */
CREATE NONCLUSTERED INDEX [IDX_T2_ID_STR] ON [dbo].[T2] 
(
	[ID_STR] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
GO

/*

в зависимости от селективности в LIKE индекс либо будет использоваться либо нет

LIKE '4555%' подхватывать индекс будет

а вот

LIKE '%4555' подхватывать индекс не будет (если вдруг захочется)

ну и в зависимости от того какие колонки в SELECT, план может измениться

при таком запросе план, как в Attache к сообщению
*/
SELECT ID
FROM T2 
WHERE rtrim(ltrim(str(CONVERT([decimal](19,0),[ID],(0))))) LIKE '519%'




Т. е. тебе не нужно даже подтягивать что-либо в твою EF Model. Текущие запросы при твоем выборе будут подхватывать индекс.

Я бы для себя делал по-другому COMPUTED колонку втянул бы в модель и так бы и писал ID_STR LIKE "44559%"
...
Рейтинг: 0 / 0
14.01.2013, 14:04
    #38109190
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Lord BritishЯ бы для себя делал по-другому COMPUTED колонку втянул бы в модель и так бы и писал ID_STR LIKE "44559%"
Плохая практика пилить модель исходя из потребностей выборок.
...
Рейтинг: 0 / 0
14.01.2013, 14:41
    #38109282
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУ,

Ну в идеале, конечно ты прав. Но лучше пусть работает быстро и гарантированно, чем красиво тормозит. Дело в том, что предложенный способ зависит от того, во что транслируется SqlFunction, с UDF конечно более детерминированно. Так что если кто-то неправильно чихнет, может индекс не подхватить. Из своего кабинета вылезут DBA, пользователи, а это не хорошо. Вобщем, варианты даны. Автор сделает по-своему. :D

netivan,
если интересно в деталях вот в Attache
...
Рейтинг: 0 / 0
14.01.2013, 14:51
    #38109305
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Lord BritishМСУ, Ну в идеале, конечно ты прав. Но лучше пусть работает быстро и гарантированно, чем красиво тормозит.
13765853 ?
...
Рейтинг: 0 / 0
14.01.2013, 14:52
    #38109310
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
"... Так что если кто-то неправильно чихнет..."

например, если вместо

Код: sql
1.
  w => SqlFunctions.StringConvert((decimal)w.ID).Trim().StartsWith(term)



напишет

Код: sql
1.
2.
3.
4.
5.
 w => SqlFunctions.StringConvert((decimal)w.ID).Trim()Trim().StartsWith(term)

или

 w => SqlFunctions.StringConvert((decimal)w.ID, 10, 5).Trim().StartsWith(term)



То Seek индекса может смениться на Scan.
...
Рейтинг: 0 / 0
14.01.2013, 14:54
    #38109314
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУ,

я согласен, твой выход наверное оптимален, но я прям в Бизнес-логике запрос этот делаю, но думаю вынести в DAL. Это так сказать @TODO, иначе скучно будет))).
Кстати ты побовал делать например select T1.*,T2.* - тогда не умрет контекст?
...
Рейтинг: 0 / 0
14.01.2013, 14:57
    #38109330
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivanКстати ты побовал делать например select T1.*,T2.* - тогда не умрет контекст?
За такие запросы нужно яйца вырывать с корнями.

P.S. И вообще, на больших наборах LIKE - плохая практика (без дополнительной фильтрации или полнотекстового индекса). Да и лайк по ID - весьма сомнительная хотелка...
...
Рейтинг: 0 / 0
14.01.2013, 14:59
    #38109338
netivan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУ,

ну тем не менее работать будет или нет с 2 таблицами?
...
Рейтинг: 0 / 0
14.01.2013, 15:00
    #38109341
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУLord BritishМСУ, Ну в идеале, конечно ты прав. Но лучше пусть работает быстро и гарантированно, чем красиво тормозит.
13765853 ?

:) я просто все рассуждения строю только из того, что автор дал ID LIKE '53535%' а для чего он это использует - не заморачиваюсь.
...
Рейтинг: 0 / 0
14.01.2013, 15:01
    #38109345
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
netivanМСУ, ну тем не менее работать будет или нет с 2 таблицами?
Я не понял твоего вопроса. Что значит "умрет контекст" и что это за запрос такой "select T1.*,T2.*"? Речь о CROSS APPLY что-ли?
...
Рейтинг: 0 / 0
14.01.2013, 15:03
    #38109352
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Lord British:) я просто все рассуждения строю только из того, что автор дал ID LIKE '53535%' а для чего он это использует - не заморачиваюсь.
Тут согласен, при учете, что "задача" автора адекватна-таки. В чем я очень сомневаюсь :)
...
Рейтинг: 0 / 0
14.01.2013, 15:12
    #38109386
Lord British
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
МСУLord British:) я просто все рассуждения строю только из того, что автор дал ID LIKE '53535%' а для чего он это использует - не заморачиваюсь.
Тут согласен, при учете, что "задача" автора адекватна-таки. В чем я очень сомневаюсь :)

Тоже сомнения с самого начала, потому открестился еще в первом посте.

Lord BritishНе спрашивая зачем это надо...

Честно говоря, решая такие скажем политкорректно "не стандартно поставленные" задачки, можно в деталях изучить загогулины ORM и посмотреть что с этим можно сделать в плане оптимизации со стороны СУБД. Полезная вещь, понимаешь. Потому и включился в беседу. Спортивный интерес, понимаешь.
...
Рейтинг: 0 / 0
14.01.2013, 15:32
    #38109433
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
как сделать ID. LIKE
Lord Britishпосмотреть что с этим можно сделать в плане оптимизации со стороны СУБД
Это да, тем более, что тюнить базу так или иначе потом придется.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / как сделать ID. LIKE / 25 сообщений из 30, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]