由于表达式树不可序列化,如何使用无法使用 WCF 工作的表达式树?
How to work with Expression Trees not working using WCF since they are not serializable?
我有一个 4 层架构项目,即 UserInterface、BusinessLogic、Service(WCF) 和 DataAccess(EF6) 层。我在我的服务上公开了接受表达式的方法,我可以将该表达式传递到我的数据访问层以使用 EF 进行评估。但是,这不起作用,因为表达式不可序列化。
在我的客户端,我希望能够构建可查询的表达式以发送到服务器端和 return 正确的投影。
服务器端:
public virtual IEnumerable<Person> Get(Expression<Func<Person, bool>> expression)
{
using (var ctx = MyContext())
{
IQueryable<PersonDto> col = ctx.DbContext.People.Where(expression);
//
return col.ToList();
}
}
客户端:
public IEnumberable<PersonDto> GetFromService(Expression<Func<PersonDto, bool>> expression)
{
using (MyService client = new MyService())
{
return client.Get(expression);
}
}
除了我这样做的方式,还有其他选择吗?表达式和函数不可序列化是否有原因?
您可以使用来自 CodePlex 的 Remote.Linq for this. The Project is currently hosted on GitHub, but it seems that there is no documentation. But you can use the old one。
最简单的实现方式(从旧文档复制的代码)
// create linq expression
System.Linq.Expressions.Expression<Func<Order, bool>> linqExpression =
order => order.Items.Where(i => i.ProductId == prodId).Sum(i => i.Quantity) > 1;
// transform linq expression into serializable expression tree
Remote.Linq.Expressions.LambdaExpression serializableExpression =
linqExpression.ToRemoteLinqExpression();
// transform serializable expression tree back into linq expression
System.Linq.Expressions.Expression<Func<Order, bool>> recreatedLinqExpression =
serializableExpression.ToLinqExpression<Order, bool>();
对于您的特定场景,将 WHERE 条件作为字符串传递并在服务器上使用动态 linq 会更简单(并且可能更安全)。
using System.Linq.Dynamic;
public virtual IEnumerable<Person> Get(string condition)
{
using (var ctx = MyContext())
{
return = ctx.DbContext.People.Where(condition).ToList();
}
}
我有一个 4 层架构项目,即 UserInterface、BusinessLogic、Service(WCF) 和 DataAccess(EF6) 层。我在我的服务上公开了接受表达式的方法,我可以将该表达式传递到我的数据访问层以使用 EF 进行评估。但是,这不起作用,因为表达式不可序列化。
在我的客户端,我希望能够构建可查询的表达式以发送到服务器端和 return 正确的投影。
服务器端:
public virtual IEnumerable<Person> Get(Expression<Func<Person, bool>> expression)
{
using (var ctx = MyContext())
{
IQueryable<PersonDto> col = ctx.DbContext.People.Where(expression);
//
return col.ToList();
}
}
客户端:
public IEnumberable<PersonDto> GetFromService(Expression<Func<PersonDto, bool>> expression)
{
using (MyService client = new MyService())
{
return client.Get(expression);
}
}
除了我这样做的方式,还有其他选择吗?表达式和函数不可序列化是否有原因?
您可以使用来自 CodePlex 的 Remote.Linq for this. The Project is currently hosted on GitHub, but it seems that there is no documentation. But you can use the old one。
最简单的实现方式(从旧文档复制的代码)
// create linq expression
System.Linq.Expressions.Expression<Func<Order, bool>> linqExpression =
order => order.Items.Where(i => i.ProductId == prodId).Sum(i => i.Quantity) > 1;
// transform linq expression into serializable expression tree
Remote.Linq.Expressions.LambdaExpression serializableExpression =
linqExpression.ToRemoteLinqExpression();
// transform serializable expression tree back into linq expression
System.Linq.Expressions.Expression<Func<Order, bool>> recreatedLinqExpression =
serializableExpression.ToLinqExpression<Order, bool>();
对于您的特定场景,将 WHERE 条件作为字符串传递并在服务器上使用动态 linq 会更简单(并且可能更安全)。
using System.Linq.Dynamic;
public virtual IEnumerable<Person> Get(string condition)
{
using (var ctx = MyContext())
{
return = ctx.DbContext.People.Where(condition).ToList();
}
}