Невозможно выполнить запрос с помощью linq в классе с принадлежащей сущностью

У меня есть такая сущность со свойством, которое отображается как принадлежащая сущность:

public class Foo
{
    public int Id { get; set; }

    public DateTimeWithTimeZone DoneAt { get; set; }
} 

public class DateTimeWithTimeZone
{
    public DateTimeOffset Time { get; set; }

    public string TimeZone { get; set; }
}

И конфигурация базы данных выглядит так:

public void Configure(EntityTypeBuilder<Foo> builder)
{
    builder.HasKey(x => x.Id);

    builder.OwnsOne(x => x.DoneAt, y =>
    {
        y.WithOwner();
        y.Property(z => z.Time).HasColumnName("DoneAt");
        y.Property(z => z.TimeZone).HasColumnName("DoneAtTimeZone");
    });
}

Я могу вставить объект Foo в базу данных с помощью EF и получить список Foos для базы данных:

var list = apiDbContext.Foos.ToList();
var list = apiDbContext.Foos.FirstOrDefault(x => x.Id == 1122);

Но когда я запрашиваю LastOrDefault:

var p = apiDbContext.Foos.LastOrDefault(x => x.Id == 1122);

Я получаю эту ошибку:

System.InvalidOperationException: 'The LINQ expression 'DbSet<Prescription>
    .Where(p => p.Id == 1122)
    .Select(p => (IncludeExpression(
        EF.Property<DateTimeWithTimeZone>(p, "DoneAt"), DoneAt)
    ))
    .Last()' could not be translated. 
Either rewrite the query in a form that can be translated, or 
switch to client evaluation explicitly 
by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync().

person Henrik Stenbæk    schedule 20.01.2020    source источник
comment
вопрос, который выходит за рамки, почему вы объявляете свой собственный класс DateTimeWithTimeZone вместо использования DateTime?   -  person Iria    schedule 20.01.2020
comment
оценка клиента отключена в EF 3.+, поэтому вместо этого эволюция выполняется в памяти. добавьте ToList() к запросу, чтобы принудительно выполнить   -  person Saif    schedule 20.01.2020
comment
@Saif: Да, это может решить эту проблему, но это не вариант, так как я хочу, чтобы запрос выполнялся на стороне сервера.   -  person Henrik Stenbæk    schedule 20.01.2020


Ответы (1)


Причина в том, что при использовании .LastOrDefault() нужно указать OrderBy.

Это работает:

var p = apiDbContext.Foos.OrderBy(x => x.Id).LastOrDefault(x => x.Filter == 1122);
person Henrik Stenbæk    schedule 20.01.2020