表达式作为参数
Expressions as parameter
我将表达式用作插入数据的参数(使用 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);
}
我有一个方法名为 Synchronize with a different expression :
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)' 方法,并且此方法无法转换为存储表达式。'
我的问题,convert/pass我的表情如何
Expression<Func<T, T, bool>>
到
Expression<Func<T, bool>>
可以通过使用自定义 ExpressionVisitor
and Expression.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
的函数委托,当根据传递的参数调用时 returns 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();
}
}
我将表达式用作插入数据的参数(使用 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);
}
我有一个方法名为 Synchronize with a different expression :
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)' 方法,并且此方法无法转换为存储表达式。'
我的问题,convert/pass我的表情如何
Expression<Func<T, T, bool>>
到
Expression<Func<T, bool>>
可以通过使用自定义 ExpressionVisitor
and Expression.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
的函数委托,当根据传递的参数调用时 returns 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();
}
}