Как я могу разделить логику на уровне объектов в запросах Entity Framework? - PullRequest
0 голосов
/ 13 июня 2018

Я хочу поделиться очень простой логикой для нескольких запросов в Entity Framework.Скажем, у меня есть следующие модели

public class User
{
    // user properties
    public ICollection<UserRole> Roles { get; set; }
}

public class UserRole : IDateRestricted
{
    public RoleType Type { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
}

public interface IDateRestricted
{
    DateTime StartDate { get; set; }
    DateTime? EndDate { get; set; }
}

Если бы я использовал обычный LINQ, я мог бы создать простой метод расширения, который позволил бы мне определить, была ли роль активна в настоящее время.

public static class DateRestrictedExtensions
{
    public static Boolean IsActive(this IDateRestricted entity)
    {
        return entity.StartDate <= DateTime.Now && (entity.EndDate == null || entity.EndDate > DateTime.Now);
    }
}

и я мог бы использовать его следующим образом.

var admins = users.Where(x => x.Roles.Any(role => role.Type == RoleType.Admin && role.IsActive()));

С структурой сущностей это терпит неудачу с ужасом:

LINQ to Entities не распознает метод Boolean IsActive(Domain.Interfaces.IDateRestricted) method, и этометод не может быть преобразован в выражение хранилища.

Есть ли способ, которым я могу поделиться этой логикой и сделать так, чтобы LINQ to Entities поддерживал ее при запросах?

1 Ответ

0 голосов
/ 13 июня 2018

Вы должны использовать Expression<Func<IDateRestricted, bool>> вместо Func<IDateRestricted, bool> - описание представленного исключения точно указывает на это:

public static class DateRestrictedExtensions
{
    public static Expression<Func<IDateRestricted, bool>> IsActive()
    {
        return entity => entity.StartDate <= DateTime.Now 
                         && (entity.EndDate == null || entity.EndDate > DateTime.Now);
    }
}

var admins = users.Where(x => x.Roles.AsQueryable().Where(role.Type == RoleType.Admin)
                                   .Any(DateRestrictedExtensions.IsActive()));
...