Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf? / 14 сообщений из 14, страница 1 из 1
12.07.2012, 11:59
    #37876267
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
EF довольно старый, до версии 4.5 (он при константе x==null и запросе ".Where(e=>e.field == x)" генерирует вместо IS NULL сравнение с null).

Но этот баг - не есть вопрос, по поводу которого был создан данный топик.

Как сделать поиск в таблице по коллекции пар значений?
Через значения одного поля вроде можно

Код: c#
1.
2.
3.
int[] table = ...;

.Where(x=>table.Contains(x.IntField))



А если ключ составной (2 int-поля)?
Id, RevisionId - загнанные в свою структуру.

Contains выдает ошибку (как в случае типа у table = List<своя_структура>, так и table = список.Select(x=>new {Id=x.Id, Revision=x.RevisionId}).ToList()).
То есть список, к которому применяется Contains, не может быть ни списком моих структур, ни списком анонимных объектов. Хотя в некоторых других местах EF анонимные объекты работают.

А у меня есть в памяти таблица составных ключей (по 2 int в каждом), соответствие которой надо найти в таблице БД.
Моя таблица
1 100
2 200
3 300
Таблица в БД
name1 1 100 89a
name2 1 150 90b
name3 2 150 0Af
name4 2 200 09j
name5 3 400 0Bf

из нее надо выбрать, значит, строки
name1 1 100 89a
name4 2 200 09j
так как первая содержит ключ (1,100), а вторая (2,200).

Какой запрос написать?

Последняя версия моего кода

Код: c#
1.
2.
3.
4.
5.
6.
7.
                    var anonymousTemplateIds = fids.Where(x => x.Id != -1).Select(x => new { x.Id, x.Revision }).ToList();

                    templates = context.Templates
                        //.Where(f => fids.Contains(new Identifier(f.TemplateId, f.TemplateRevisionId)))
                        //.Where(f => fids.Any(fid=> fid.Id == f.TemplateId && fid.Revision == f.TemplateRevisionId))
                        .Where(f => anonymousTemplateIds.Contains(new { Id = f.TemplateId, Revision = f.TemplateRevisionId }))
                        .ToList();



Unable to create a constant value of type 'Anonymous type'. Only primitive types ('such as Int32, String, and Guid') are supported in this context.
...
Рейтинг: 0 / 0
13.07.2012, 11:08
    #37877779
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Так как Вы решаете данную проблему?

Кстати, баг - в коде "int[]" буква "t" голубая, а не синяя
...
Рейтинг: 0 / 0
13.07.2012, 12:02
    #37877881
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Как-то сделал с помощью преобразования двух INT в новое поле,
впрочем, (long) можно было бы и не писать в Select и Contains, результат был бы тот же,

Код: c#
1.
2.
3.
4.
5.
        const long MAX_UINT_PLUS_1 = (long)uint.MaxValue + 1L;
                    var complexIds = ids.Where(f => f.Id != -1).Select(f => MAX_UINT_PLUS_1 * (long)f.Id + (long)f.Revision).ToList();
                    templates = context.Templates
                        .Where(f => complexIds.Contains(MAX_UINT_PLUS_1 * (long)f.TemplateId + (long)f.TemplateRevisionId))
                        .ToList();



Имеем проблему

Код: 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.
SELECT 
[Extent1].[DirectionCode] AS [DirectionCode], 
[Extent1].[Name] AS [Name], 
[Extent1].[Type] AS [Type], 
[Extent1].[ParamsData] AS [ParamsData], 
[Extent1].[TemplateId] AS [TemplateId], 
[Extent1].[TemplateRevisionId] AS [TemplateRevisionId], 
[Extent1].[Mass] AS [Mass], 
[Extent1].[ApprovalDate] AS [ApprovalDate], 
[Extent1].[LastChangeDate] AS [LastChangeDate], 
[Extent1].[Profile] AS [Profile], 
[Extent1].[Grade] AS [Grade]
FROM (SELECT 
      [Template].[TemplateId] AS [TemplateId], 
      [Template].[TemplateRevisionId] AS [TemplateRevisionId], 
      [Template].[Name] AS [Name], 
      [Template].[ApprovalDate] AS [ApprovalDate], 
      [Template].[LastChangeDate] AS [LastChangeDate], 
      [Template].[Type] AS [Type], 
      [Template].[Profile] AS [Profile], 
      [Template].[Grade] AS [Grade], 
      [Template].[DirectionCode] AS [DirectionCode], 
      [Template].[ParamsData] AS [ParamsData], 
      [Template].[Mass] AS [Mass]
      FROM [vrsn].[Template] AS [Template]) AS [Extent1]
WHERE (1219770717496 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1194000913707 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (949187775457 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1292785161495 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1082331764043 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1267015356940 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1108101566660 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1206885815613 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1009317319579 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (983547516234 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1181116010185 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1095216665051 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1254130455456 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (914828039081 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1013612287278 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1146756273491 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1099511632058 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1258425423085 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1284195226372 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1198295879194 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1086626731330 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1245540520142 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1271310324947 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1236950586549 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (940597839548 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1249835487586 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1039382090037 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1090921698226 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1224065684723 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1151051239500 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1176821043641 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1262720389630 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1228360651731 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1202590848284 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1155346208027 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1275605292096 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (231928233984 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1241245552989 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1056561958968 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1017907251206 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1116691501403 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1142461305866 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1189705946413 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) OR (1288490193725 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))



Почему не
Код: sql
1.
WHERE (((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) in (1194000913707, 949187775457, 1292785161495 ...)
...
Рейтинг: 0 / 0
16.07.2012, 16:54
    #37880965
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Кто-нибудь поможет?
...
Рейтинг: 0 / 0
16.07.2012, 18:50
    #37881179
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
...
Рейтинг: 0 / 0
18.07.2012, 11:08
    #37883296
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
buser,

Спасибо, но в примере, как я понял, решается проблема, когда принимается только 1 аргумент (ключ), а чтобы передать туда составной ключ, предлагают сделать анонимный объект. У меня так уже сделано. А проблема есть.

То есть, возможно ли как-то переписать код, чтобы в запросе было in()? Я вроде находил какие-то пользовательские переопределения генерации запросов EF, которые могли это делать...
...
Рейтинг: 0 / 0
18.07.2012, 13:24
    #37883636
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Поливанов Алексей, я наверное не понял Вас... IN по двум полям? Чем вам Join или Intecept не подходит?

Код: c#
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.
47.
public struct Test
	{
	 public int Id;
	 public int RevisionId;
	 public string SomeVal;
	};

public struct Key
	{
	 public int Id;
	 public int RevisionId;	
	}

void Main()
{

	
	var tags = new List<Test>() 
		{ 
			new Test() {Id = 1, RevisionId = 100, SomeVal = "tag1"}, 
			new Test() { Id = 2, RevisionId = 201, SomeVal = "tag2" }, 
			new Test() { Id = 3,  RevisionId = 300, SomeVal = "tag3" } 
		};
	
	tags.Dump();
	
	var keys = new List<Key>()
		{
			new Key() { Id = 2, RevisionId = 201 }, 
			new Key() { Id = 3,  RevisionId = 300} 		
		};
	
	var query = tags.Join(keys, 
							e => new Key() {Id = e.Id, RevisionId = e.RevisionId}, 
							o =>  new Key() {Id = o.Id, RevisionId = o.RevisionId},
							(e,o) => e.SomeVal);
	query.Dump();
	
	var query1 = keys.Intersect(tags.Select(t => new Key(){Id = t.Id, RevisionId = t.RevisionId}))
	                    .Join(tags, 
							e => new Key() {Id = e.Id, RevisionId = e.RevisionId}, 
							o =>  new Key() {Id = o.Id, RevisionId = o.RevisionId},
							(e,o) => o.SomeVal						
						);
	
	query1.Dump();
}

...
Рейтинг: 0 / 0
19.07.2012, 15:55
    #37885627
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
buser,

Ладно, попробую свой Contains заменить на Intersect. Может, поможет.
Проблема в том, что NHibernate Entity Framework генерирует неоптимальные запросы. Вместо

Код: sql
1.
WHERE (((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) in (1194000913707, 949187775457, 1292785161495 ...)



он пишет колоссальное

Код: 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.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
SELECT 
[Extent1].[DirectionCode] AS [DirectionCode], 
[Extent1].[Name] AS [Name], 
[Extent1].[Type] AS [Type], 
[Extent1].[ParamsData] AS [ParamsData], 
[Extent1].[TemplateId] AS [TemplateId], 
[Extent1].[TemplateRevisionId] AS [TemplateRevisionId], 
[Extent1].[Mass] AS [Mass], 
[Extent1].[ApprovalDate] AS [ApprovalDate], 
[Extent1].[LastChangeDate] AS [LastChangeDate], 
[Extent1].[Profile] AS [Profile], 
[Extent1].[Grade] AS [Grade]
FROM (SELECT 
      [Template].[TemplateId] AS [TemplateId], 
      [Template].[TemplateRevisionId] AS [TemplateRevisionId], 
      [Template].[Name] AS [Name], 
      [Template].[ApprovalDate] AS [ApprovalDate], 
      [Template].[LastChangeDate] AS [LastChangeDate], 
      [Template].[Type] AS [Type], 
      [Template].[Profile] AS [Profile], 
      [Template].[Grade] AS [Grade], 
      [Template].[DirectionCode] AS [DirectionCode], 
      [Template].[ParamsData] AS [ParamsData], 
      [Template].[Mass] AS [Mass]
      FROM [vrsn].[Template] AS [Template]) AS [Extent1]
WHERE (1219770717496 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))
OR (1194000913707 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))
OR (949187775457 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))
OR (1292785161495 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))
OR (1082331764043 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1267015356940 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1108101566660 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1206885815613 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1009317319579 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (983547516234 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1181116010185 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1095216665051 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1254130455456 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (914828039081 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1013612287278 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1146756273491 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1099511632058 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1258425423085 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1284195226372 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1198295879194 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1086626731330 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1245540520142 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1271310324947 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1236950586549 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (940597839548 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1249835487586 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1039382090037 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1090921698226 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1224065684723 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1151051239500 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1176821043641 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1262720389630 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1228360651731 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1202590848284 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1155346208027 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1275605292096 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (231928233984 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1241245552989 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1056561958968 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1017907251206 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1116691501403 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1142461305866 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1189705946413 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint))) 
OR (1288490193725 = ((cast(4294967296 as bigint) *  CAST( [Extent1].[TemplateId] AS bigint)) +  CAST( [Extent1].[TemplateRevisionId] AS bigint)))
...
Рейтинг: 0 / 0
19.07.2012, 16:24
    #37885710
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Если вы писали запросы, то наверное понимаете, что хрен редьки не слаще, т.е. оба запроса неоптимальны...
...
Рейтинг: 0 / 0
23.07.2012, 10:53
    #37888803
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
По поводу Intersect, это из той же оперы , что и Join, нам сейчас C# на такой код выдает ошибку:
Код: sql
1.
                        .Join(fgosesIds.Select(i => new { FgosTemplateId = i.Id, FgosTemplateRevisionId = i.Revision }), s => new { s.FgosTemplateId, s.FgosTemplateRevisionId }, d => new { d.FgosTemplateId, d.FgosTemplateRevisionId }, (s, d) => s)



Unable to create a constant value of type "Anonymous type". Only primitive types ('such as Int32, String, and Guid') are supported in this context.

Есть подозрение, что при Intersect будет то же самое.

По поводу неоптимальности - до этого было N запросов на каждую пару (а их сейчас полсотни)! вместо одного. ИМХО, лучше один неоптимальный...

Сейчас пытаемся слить не int+int->long, а int->string. То есть преобразовать int в строку средствами EF.

Но EF не понимает в лямбдах string.Format("{0},{1}",...,...) и .ToString(). Может, (string)id поможет.
Можно ли как-то не через преобразование int в long, а через преобразование int в string заменить два поля одним?
...
Рейтинг: 0 / 0
23.07.2012, 11:06
    #37888831
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Вот, нашел

Надо использовать SqlFunctions.StringConvert
http://stackoverflow.com/questions/4502842/int-to-string-in-entity-framework

Однако

Код: sql
1.
2.
3.
4.
5.
                        .Join(fgosesIds.Select(i => string.Format(identifierFormat, i.Id, i.Revision)).ToList(),
                                s => SqlFunctions.StringConvert((double)s.FgosTemplateId) + "," + SqlFunctions.StringConvert((double)s.FgosTemplateRevisionId),
                                //s => Convert.ToString(s.FgosTemplateId) + "," + Convert.ToString(s.FgosTemplateRevisionId),
                                d => d,
                                (s, d) => s)



An error occurred while executing the command definition. See the inner exception for details.
Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries.

Поищу, нет ли там чего-то вроде SQLFunctions.MergeStrings() вместо + ?
...
Рейтинг: 0 / 0
23.07.2012, 13:09
    #37889071
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Вобщем я набрехал...
Но, все равно, оставьте вы свою идею... компактный запрос не значит оптимальный... вы либо структуру таблицы переделайте... либо одно из двух - вью, хранимая процедура... вашим индексам п-ц... такой запрос - скан таблицы...

Код: 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.
/*
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Templates](
	[Name] [nvarchar](50) NULL,
	[TemplateId] [int] NULL,
	[RevisionId] [int] NULL,
	[SomeData] [nvarchar](50) NULL
)

insert  into dbo.Templates
        ( Name ,
          TemplateId ,
          RevisionId ,
          SomeData
        )
values  
('name1', 1, 100, '89a'),
('name2', 1, 150, '90b'),
('name3', 2, 150, '0Af'),
('name4', 2, 200, '09j'),
('name5', 3, 400, '0Bf')
*/



Dynamically Composing Expression Predicates


Код: c#
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.
public struct Key
	{
	 public int? Id;
	 public int? RevisionId;	
	}

void Main()
{
	var keys = new List<Key>()
		{
			new Key() { Id = 1, RevisionId = 100 }, 
			new Key() { Id = 2,  RevisionId = 200},	
			new Key() { Id = 3,  RevisionId = 300}
		};	
		

	var query = Templates.Where(t=>false);

	foreach(var key in keys)
	{
		int? TemplateId = key.Id, RevisionId = key.RevisionId;
		query = query.Union(Templates.Where(tm => tm.TemplateId == TemplateId && tm.RevisionId == RevisionId));
	}

	query.ToList();
}


...
Рейтинг: 0 / 0
24.07.2012, 11:15
    #37890189
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
buser,

Спасибо за помощь.
Может быть, попробуем сделать импортируемую хранимку или View.
Только хранимка вряд ли примет от EF целый массив значений, а View - должно иметь 1 поле (string либо long) вместо 2-х int, так?
...
Рейтинг: 0 / 0
24.07.2012, 12:27
    #37890316
buser
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf?
Ага - так... А в процу можно передать набор идишников или ексемль (см. Массивы и списки в SQL), да в Linq2Sql и EF можно директом слать запросы и транслировать результаты в набор сущностей... ну типа на самый край :)
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Entity Framework (EF) Как осуществить поиск по таблице по слож. ключу (2 поля) ч-з OneOf? / 14 сообщений из 14, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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