Linq to SQL Странный перевод SQL - PullRequest
3 голосов
/ 18 февраля 2011

У меня есть простой запрос, который генерирует некоторые странные переводы SQL, который взрывает мой код, когда объект насыщен.

from x in DataContext.MyEntities
select new 
{
    IsTypeCDA = x.EntityType == "CDA" 
}

Я ожидаю, что этот запрос должен быть переведен в:

SELECT (CASE WHEN [t0].[EntityType] = @p1 THEN 1 ELSE 0 END) as [IsTypeCDA]
...

Вместо этого я получаю это:

SELECT 
(CASE 
    WHEN @p1 = [t0].[EntityType] THEN 1
    WHEN NOT (@p1 = [t0].[EntityType]) THEN 0
    ELSE NULL
 END) AS [IsTypeCDA]
... 

Поскольку я насыщаю POCO, где IsTypeCDA является bool, он взрывается, заявляя, что я не могу присвоить null bool.

Есть мысли?

Редактировать: исправлены имена свойств, чтобы они имели смысл ...

Ответы [ 3 ]

2 голосов
/ 18 февраля 2011
from x in DataContext.MyEntities
select new
{
  IsTypeCDA = x.EntityType == null 
}

c # интерпретация (false) или sql интерпретация (null)?

Это работает в sql, так что sql интерпретация.Вот почему перевод в стиле фанк - операция действительно возвращает недействительный бул.

Используйте этот запрос, чтобы превратить этот обнуляемый бул в обычный старый бул.

from x in DataContext.MyEntities
select new
{
  IsTypeCDA = ((bool?)(x.EntityType == "CDA")) ?? false
}
1 голос
/ 18 февраля 2011

Linq to SQL выполняет "странное" сравнение, поскольку значения базы данных могут быть NULL. К сожалению, это не очень хорошо переводит трехзначный результат сравнения. На первый взгляд, я удивляюсь, почему у любых ваших сущностей есть NULL для их EntityType. Изменение схемы для запрета значений NULL было бы самым простым решением.

Однако, если таблица определена таким образом по законным деловым причинам, вы можете обойти ее несколькими способами.

Во-первых, вы можете объединить NULL s в значение заполнителя.

from x in DataContext.MyEntities
select new 
{
    IsTypeCDA = (x.EntityType ?? "") == "CDA" 
}

Альтернативно, использование String.Equals создает более тщательное сравнение, которое обрабатывает NULL s.

from x in DataContext.MyEntities
select new 
{
    IsTypeCDA = string.Equals(x.EntityType, "CDA")
}

Ни один из них не сгенерирует простой SQL, который вы ожидали, но они оба выполнят свою работу.

0 голосов
/ 18 февраля 2011

Я бы взял IsTypeCDA в качестве свойства только для получения и выбрал бы в этом классе:

public class SomeName
{
    public string EntityType { get; set; }
    public bool IsTypeCDA { get { return EntityType == EntityType.CDA; } }
}

...

from x in DataContext.MyEntities
select new SomeName
{
    EntityType = x.EntityType
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...