Изменяет ли Roslyn способ компиляции выражения, использующего перечисление Nullable?

Следующий код печатает разные результаты между VS2015 и VS2013:

namespace ConsoleApplication1
{
    enum YesNo
    {
        Yes,
        No
    }

    class MyType
    {
        public string Name { get; set; }
        public YesNo? YesNo { get; set; }        
    }

    class Program
    {
        static void Main(string[] args)
        {

            Expression<Func<MyType, bool>> expr = (MyType x) => x.YesNo == YesNo.Yes;
            Console.WriteLine(expr.ToString());

            Console.ReadLine();
        }
    }

}

Результат VS2013 (без установленного VS2015):

x => (Convert(x.YesNo) == Convert(Yes))

Однако результат VS2015:

x => (Convert(x.YesNo) == Convert(Convert(Yes)))

Эта разница в настоящее время вызывает у нас проблемы. Также клиент Telerik обнаружил ту же проблему

Мы используем BLToolkit для доступа к данным, текущая проблема заключается в следующем:

Изначально (чисто на VS2013)

People.Where(i=>i.YesNo == Yes.Yes)

будет преобразован в

x => (Convert(x.YesNo) == Convert(Yes))

а затем преобразуется в

x => x.YesNo == Y

а затем в конечном итоге переводится в SQL

select * from Person p
where p.YesNo = 'Y'

что является правильным результатом.

Однако теперь тот же запрос (выражение) переведен в

x => (Convert(x.YesNo) == Convert(Convert(Yes)))

который превращается в

x => x.YesNo == Convert(Y)
then
x => x.YesNo == 1

затем это переводится в SQL

select * from Person p
where p.YesNo = '1'

что для нас неожиданно.

Эта разница вызвана дизайном или это ошибка?

Эта проблема вызвана компилятором .NET Roslyn или .NET 4.6?


person Jeff Chen    schedule 05.08.2015    source источник
comment
Думаю, этот вопрос лучше задать на github.com/dotnet/roslyn   -  person MarcinJuraszek    schedule 05.08.2015
comment
Да, я припоминаю, что что-то изменилось в определенном значении перечисления в Roslyn. Вы бы сказали, что это связано с этим ?   -  person Jeroen Vannevel    schedule 05.08.2015
comment
Я помню, как читал, что Roslyn изменила выражения для перечислений. Это не ошибка, выражение все еще в силе, просто другое (что не поможет вам, если у вас есть инструменты, которые жестко запрограммированы для работы в старом стиле). Интересно, что x.YesNo.Value == YesNo.Yes генерирует старый стиль, из-за чего кажется, что он связан с обработкой перечислений Nullable.   -  person Will    schedule 05.08.2015
comment
@Will, да, x.YesNo.Value == YesNo.Yes порождает старый стиль. Я тоже это обнаружил. Однако это означает, что вам нужно постоянно проверять значение null или использовать Nullable ‹T› .GetValueOrDefault, если вы хотите использовать какое-нибудь перечисление с Nullable.   -  person Jeff Chen    schedule 05.08.2015
comment
Поскольку YesNo в конечном итоге является числовым, я очень удивлен, что он генерирует строковые литералы в SQL. Я ожидал увидеть 1, а не 'Y' - как это вообще могло быть порезано ?! Судя по всему, здесь с BLToolkit происходит больше, может быть, какая-то конфигурация, которая определяет сопоставления? В конечном итоге похоже, что BLToolkit нуждается в обновлении для работы с новыми выражениями, сгенерированными Roslyn.   -  person Will    schedule 05.08.2015
comment
@Will, ты прав. Мы пришли к выводу, что BLToolkit нуждается в обновлении. Мы исправили это из исходного кода BLToolkit.   -  person Jeff Chen    schedule 05.08.2015