linq case поведение на заявка с анонимни типове

Имам следната заявка за linq

var result = from myTypes in context.MyTypes
where
  ((myTypes .Prop1== "Test" ? 1 : 0) + 
  (myTypes .Prop2 == "Tester2" ? 1 : 0) + 
  (myTypes .Prop3 == "624642624000000000" ? 1 : 0) + 
  (myTypes .Prop4 == "TS166TH" ? 1 : 0) + 
  (myTypes .Prop5 == "1 Test Lane" ? 1 : 0)) >= 4
  select new {
  myTypes .Prop1,
  myTypes .Prop2,
  myTypes .Prop3,
  myTypes .Prop4,
  myTypes .Prop5,
  myTypes .OtherProp,
  myTypes .OtherTypeId
};

result.ToList();

Това води до следния очакван SQL, който искам да постигна

SELECT 
[Extent1].[Prop1] AS [Prop1], 
[Extent1].[Prop2] AS [Prop2], 
[Extent1].[Prop3] AS [Prop3], 
[Extent1].[Prop4] AS [Prop4], 
[Extent1].[Prop5] AS [Prop5], 
[Extent1].[OtherProp] AS [OtherProp], 
[Extent1].[OtherTypeId] AS [OtherTypeId],

FROM [dbo].[MyType] AS [Extent1]
WHERE ((CASE WHEN ('Test' = [Extent1].[Prop1]) THEN 1 ELSE 0 END) + (CASE WHEN ('Tester2' = [Extent1].[Prop2]) THEN 1 ELSE 0 END) + (CASE WHEN ('624642624000000000' = [Extent1].[Prop3]) THEN 1 ELSE 0 END) + (CASE WHEN ('TS166TH' = [Extent1].[Prop4]) THEN 1 ELSE 0 END) + (CASE WHEN ('1 Test Lane' = [Extent1].[Prop5]) THEN 1 ELSE 0 END)) >= 4

Въпреки това искам да върна MyType, а не анонимен тип, затова написах следното

var result = from myTypes in context.MyTypes
where
  ((myTypes .Prop1== "Test" ? 1 : 0) + 
  (myTypes .Prop2 == "Tester2" ? 1 : 0) + 
  (myTypes .Prop3 == "624642624000000000" ? 1 : 0) + 
  (myTypes .Prop4 == "TS166TH" ? 1 : 0) + 
  (myTypes .Prop5 == "1 Test Lane" ? 1 : 0)) >= 4
  select myTypes; 

result.ToList();

Което бих очаквал да генерира същата заявка, но да върне моя тип. Вместо това намирам, че изпълнява масивна рекурсивна заявка (по същество запитва всеки запис в таблицата), както по-долу.

SELECT 
[Extent1].[Prop1] AS [Prop1], 
[Extent1].[Prop2] AS [Prop2], 
[Extent1].[Prop3] AS [Prop3], 
[Extent1].[Prop4] AS [Prop4], 
[Extent1].[Prop5] AS [Prop5],
[Extent1].[OtherProp] AS [OtherProp],
[Extent1].[OtherTypeId] AS [OtherTypeId],
FROM [dbo].[MyType] AS [Extent1]
WHERE ((CASE WHEN ('Test' = [Extent1].[Prop1]) THEN 1 ELSE 0 END) + (CASE WHEN ('Tester2' = [Extent1].[Prop2]) THEN 1 ELSE 0 END) + (CASE WHEN ('624642624000000000' = [Extent1].[Prop3]) THEN 1 ELSE 0 END) + (CASE WHEN ('TS166TH' = [Extent1].[Prop4]) THEN 1 ELSE 0 END) + (CASE WHEN ('1 Test Lane' = [Extent1].[Prop5]) THEN 1 ELSE 0 END)) >= 4
GO

SELECT 
[Extent1].[OtherTypeId] AS [OtherTypeId], 
[Extent1].[OtherTypeProp] AS [OtherTypeProp], 
FROM [dbo].[OtherTypes] AS [Extent1]
GO

-- Region Parameters
DECLARE EntityKeyValue1 BigInt = 1
-- EndRegion
SELECT 
[Extent1].[Prop1] AS [Prop1], 
[Extent1].[Prop3] AS [Prop2], 
[Extent1].[Prop3] AS [Prop3], 
[Extent1].[Prop4] AS [Prop4], 
[Extent1].[Prop5] AS [Prop5], 
[Extent1].[OtherProp] AS [OtherProp], 

WHERE [Extent1].[OtherTypeId] = @EntityKeyValue1
GO

-- Region Parameters
DECLARE EntityKeyValue1 BigInt = 2
-- EndRegion
SELECT 
[Extent1].[Prop1] AS [Prop1], 
[Extent1].[Prop3] AS [Prop2], 
[Extent1].[Prop3] AS [Prop3], 
[Extent1].[Prop4] AS [Prop4], 
[Extent1].[Prop5] AS [Prop5], 
[Extent1].[OtherProp] AS [OtherProp], 

WHERE [Extent1].[OtherTypeId] = @EntityKeyValue1
GO

Изглежда, че получава всички типове fk за ВСЕКИ запис и игнорира клаузата where?

Може ли някой да обясни какво правя погрешно тук и защо двете генерирани заявки са различни?


person Sheff    schedule 04.08.2011    source източник
comment
Какъв SQL се произвежда от последния пример?   -  person Brian Dishaw    schedule 04.08.2011
comment
Можете ли да публикувате MyType код?   -  person Jacek Gorgoń    schedule 04.08.2011
comment
MyType е просто клас обект с 6-те свойства (виждани в примера) в него.   -  person Sheff    schedule 05.08.2011
comment
Актуализирах въпроса, така че имате предвид какво ще се случи, ако избера нов { myTypes }. ще опитам   -  person Sheff    schedule 05.08.2011
comment
Получавам същия резултат. Изглежда се опитва да получи FK типовете за myType, но за ВСИЧКИ записи и игнорира клаузата where.   -  person Sheff    schedule 05.08.2011
comment
Искам обаче да върна MyType, а не анонимен тип -- Тогава просто напишете new MyType { … } вместо new { … }!   -  person stakx - no longer contributing    schedule 05.08.2011
comment
@stakx И очевидна точка. Не бях мислил просто да инициализирам типа и да настроя всички подпори ръчно   -  person Sheff    schedule 05.08.2011


Отговори (1)


Добре, това беше неудобно.

Използвах LinqPad, за да тествам заявката и извиквах Dump() на резултата ToList(). Dump() изброява всички свойства, които са причинили циклично изброяване през всички свързани записи в db. Където като Dump на анонимните типове просто се изброяват всички свойства и нито един обект Навигационните свойства не причиняват изброяване.

Бележка за всички, които в бъдеще ще използват метода Dump() на LinqPad за Entity. Извинения на всички за загубата на време. Грешка на ученик.

person Sheff    schedule 05.08.2011