由于表达式树不可序列化,如何使用无法使用 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();
        }
    }

更多信息在这里:Using the LINQ Dynamic Query Library