表达式作为参数

时间:2017-04-24 15:50:28

标签: c# entity-framework linq-to-entities

我使用表达式作为插入数据的参数(使用EF):

public bool Exists(Expression<Func<V, bool>> predicate)
{
    return _dbContext.Set<V>().Any(predicate);
}

public void AddIfNotExists(V entity, Expression<Func<V, bool>> predicate)
{
    if (!Exists(predicate))
        Add(entity);
}

我有一个方法nammed使用不同的表达式进行同步:

protected void Synchronize<T>(string resource, Expression<Func<T, T, bool>> predicate) where T : class
{
    var list = _context.RestClient.Get<List<T>>(resource);

    using (var repo = new Repository<GmaoContext, T>())
    {
        list.ForEach(x =>
        {
            repo.AddIfNotExists(x, y => predicate.Compile().Invoke(x, y));
        });

        repo.Save();
    }
}

我的方法Synchronize:

需要两个参数
Synchronize<ClientLivraison>("clientlivraison", (x, y) => x.IdClientJuridique == y.IdClientJuridique && x.IdClientLivraison == y.IdClientLivraison);

在运行时,我有这个例外:

System.NotSupportedException:'LINQ to Entities无法识别方法'Boolean Invoke(Manuloc.Gmao.SynchroDb.Entity.Origine,Manuloc.Gmao.SynchroDb.Entity.Origine)'方法,而且这个方法不能被翻译成商店表达。'

我的问题,如何转换/传递我的表达

Expression<Func<T, T, bool>>

Expression<Func<T, bool>>

1 个答案:

答案 0 :(得分:1)

可以使用自定义ExpressionVisitorExpression.Lambda方法替换第一个或第二个参数,将Expression<Func<T, T, bool>>转换为Expression<Func<T, bool>>

但更简单,更自然的方法是更改​​Synchronize方法参数

Expression<Func<T, T, bool>> predicate

Func<T, Expression<Func<T, bool>>> predicateFactory>

即。一个带参数T的函数委托,调用时会根据传递的参数返回Expression<Func<T, bool>>

从调用者的角度来看,这将是一个改变的问题

(x, y) => x.IdClientJuridique == y.IdClientJuridique && x.IdClientLivraison == y.IdClientLivraison

x => y => x.IdClientJuridique == y.IdClientJuridique && x.IdClientLivraison == y.IdClientLivraison

并且实施将简单地替换

repo.AddIfNotExists(x, y => predicate.Compile().Invoke(x, y));

repo.AddIfNotExists(x, predicateFactory(x));

以下是整个方法:

protected void Synchronize<T>(string resource, Func<T, Expression<Func<T, bool>>> predicateFactory) where T : class
{
    var list = _context.RestClient.Get<List<T>>(resource);

    using (var repo = new Repository<GmaoContext, T>())
    {
        list.ForEach(x =>
        {
            repo.AddIfNotExists(x, predicateFactory(x));
        });

        repo.Save();
    }
}