2017-02-21 29 views
0

Предполагая, что у меня есть сущность:EF6: Материализовать данные, используя пользовательский тип

public class Event 
{ 
    ... 
    public DateTime At { get; set; } 
} 

, а также модель объект:

public class Something 
{ 
    ... 
    public Date At { get; set; } 
} 

где дата является пользовательским типом, который может быть неявно преобразован из DateTime:

public struct Date 
{ 
    public Date(DateTime value) 
    { 
     ... 
    } 
    ... 
    public static implicit operator Date(DateTime value) 
    { 
     return new Date(value); 
    } 
} 

То, что я пытаюсь сделать, это извлечь данные из базы данных в модели:

var events = db.Events 
    .Select(x => new Something 
    { 
     ... 
     At = x.At, 
    }) 
    .ToList(); 

И, конечно, это не удается за исключением следующего:

Невозможно бросить тип «System.DateTime» к типу «SMG.Web.Date». LINQ to Entities поддерживает только листинг EDM-примитивов или типов перечислений.

Да, я знаю, что я мог бы достичь того, что мне нужно, с помощью какого-либо временного объекта, материализовать значение DateTime в память и затем преобразовать его в мой пользовательский тип. Но что, если я предпочитаю не использовать эту стратегию и хочу сделать это за один шаг.

Вопрос: Есть ли способ научить LINQ Entities, как относиться к моей пользовательской дате с той стороны реальности?

+0

Do 'ToList()' перед 'Select (...)' – DavidG

+1

Вы действительно его прочитали? – drty

+0

Да, именно поэтому я прокомментировал вместо ответа. – DavidG

ответ

1

Ваш выбор неправильный. Перепишите его как:

public struct Date 
{ 
    public Date(DateTime value) 
    { 
     DateTimeValue = value; 
    } 

    // Or whatever your field or property is called 
    public DateTime DateTimeValue { get; } 

    public static implicit operator DateTime(Date date) 
    { 
     return date.DateTimeValue; 
    } 
} 

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

+0

Вы действительно попробовали это в запросе LINQ-to-Entities? –

+0

Нечто похожее. По общему признанию, я использовал LINQPad для его проверки, но он сгенерировал правильный SQL с EF 6.1.3. –

+0

Я бы ожидал, что EF будет генерировать исключение, потому что он не знает тип 'Date': он не является отображенным типом и не находится в его коллекции известных сопоставлений типов. По-видимому, он просто пытается присвоить DateTime любому свойству, сопоставленному столбцу «DateTime» в базе данных, и ему удается, когда свойство accepting успешно завершит «глотание» значения «DateTime». Конечно, это не сработало бы в коде, потому что EF даже не смог бы создать столбец базы данных из неизвестного типа для начала. –