Как реорганизовать запрос LINQ для использования делегата или выражения <Func <T, bool >> - PullRequest
0 голосов
/ 26 января 2012

Этот метод прекрасно работает и генерирует только 1 запрос (используя .Include () для быстрой загрузки). Тем не менее, я хотел бы изменить код AbleToDelete, чтобы сделать его более пригодным для повторного использования. (С использованием EF4)

        public override IEnumerable<AffectProjection> SelectAll(SearchAffects page)
        {
            IQueryable<Affect> query = BuildSearchQuery(page);

            IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection()
            {
                AffectID = entity.AffectID,
                AffectCode = entity.AffectCode,
                AffectName = entity.AffectName,

                AbleToDelete = !((entity.Foo1s.Any(pa => !pa.Inactive))
                                || (entity.Foo2s.Any(ea => !ea.Inactive))
                                || (entity.Foo3s.Any(sa => !sa.Inactive))
                                || (entity.Foo4s.Any(spa => !spa.Inactive)))
            }).ToArray();

            return results;
        }

Я переместил код в структуру Expression Func, но не могу понять, как заменить мой код, который устанавливает свойство AbleToDelete. Посоветуйте?

public Expression<Func<Affect, bool>> DelegateExpression = entity =>
            !((entity.Foo1s.Any(pa => !pa.Inactive))
                || (entity.Foo2s.Any(ea => !ea.Inactive))
                || (entity.Foo3s.Any(sa => !sa.Inactive))
                || (entity.Foo4s.Any(spa => !spa.Inactive)));

И последнее, но не менее важное: это решение компилируется, но завершается с ошибкой во время выполнения с ошибкой: «NotSupportedException - Тип узла выражения LINQ« Invoke »не поддерживается в LINQ to Entities». Попытка использовать делегата, который не поддерживается:

        public override IEnumerable<AffectProjection> SelectAll(SearchAffects page)
        {
            IQueryable<Affect> query = BuildSearchQuery(page);

            //Create delegate instance and register method -- single statement
            var deleteAbilityAllowed = new CanDelete(GetAbleToDelete);

            IEnumerable<AffectProjection> results = query.Select(entity => new AffectProjection()
            {
                AffectID = entity.AffectID,
                AffectCode = entity.AffectCode,
                AffectName = entity.AffectName,

                AbleToDelete = deleteAbilityAllowed(entity)
            }).ToArray();

            return results;
        }

        public delegate bool CanDelete(Affect entity);

        public bool GetAbleToDelete(Affect entity)
        {
            return !((entity.Foo1s.Any(pa => !pa.Inactive))
                || (entity.Foo2s.Any(ea => !ea.Inactive))
                || (entity.Foo3s.Any(sa => !sa.Inactive))
                || (entity.Foo4s.Any(spa => !spa.Inactive)));
        }

Пожалуйста, сообщите и заранее спасибо!

1 Ответ

2 голосов
/ 26 января 2012

LINQKit содержит методы, которые позволяют вам сделать это.С ним вы можете использовать yout DelegateExpression.Чтобы сделать это, добавьте AsExpandable() к источнику вашего запроса и затем вызовите выражение, используя Invoke():

var expression = DelegateExpression;

var results = query.AsExpandable().Select(entity => new AffectProjection()
{
    AffectID = entity.AffectID,
    AffectCode = entity.AffectCode,
    AffectName = entity.AffectName,
    AbleToDelete = expression.Invoke(entity)
}).ToArray();

Будьте осторожны, кажется, вы не можете использовать выражение непосредственно из поля, он должен быть из локальной переменной.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...