C# 表达式:当我有表达式来获取ID时,是一个获取ID选择器吗?

C# 表达式:当我有表达式来获取ID时,是一个获取ID选择器吗?,c#,linq-to-entities,expression-trees,C#,Linq To Entities,Expression Trees,我有一个用于LINQtoEntities的通用基本存储库类,可以根据ID选择实体 为了将其子类化,您需要实现以下两个: protected override Expression<Func<User, bool>> GetByIDSelector(int id) { return u => u.UserID == id; } protected override Expression<Func<User, int>> KeySelect

我有一个用于LINQtoEntities的通用基本存储库类,可以根据ID选择实体

为了将其子类化,您需要实现以下两个:

protected override Expression<Func<User, bool>> GetByIDSelector(int id)
{
  return u => u.UserID == id;
}

protected override Expression<Func<User, int>> KeySelector
{
  get { return u => u.UserID; }
}
其中,
GetByIdSelector
如下所示,它应该将
KeySelector
表达式转换为一个可以通过ID进行选择的表达式

private Expression<Func<TDataModel, bool>> GetByIdSelector(TKey id)
{
  return Expression.Lambda<Func<TDataModel, bool>>
  (
    Expression.Equal(KeySelector.Body,
    Expression.Constant(id)), 
    KeySelector.Parameters.Single()
  );
}
专用表达式GetByIdSelector(TKey id)
{
返回表达式.Lambda
(
表达式.Equal(KeySelector.Body,
表达式.常量(id)),
KeySelector.Parameters.Single()
);
}
但是,实体框架抛出一个异常,即传入的参数未绑定到查询

参数“u”未绑定在指定的LINQ to Entities查询表达式中


有没有什么方法可以干净地重用
KeySelector
表达式而不必重建整个表达式?

这不起作用的原因是,每次调用
this.KeySelector
,它都在创建一个全新的lambda表达式(因此调用
KeySelector.Parameters.Single()
与用于
KeySelector.Body的参数不同。将该表达式缓存到一个变量中,如下所示,它将起作用

private Expression<Func<TDataModel, bool>> GetByIdSelector(TKey id)
{
    var keySelector = KeySelector;
    return Expression.Lambda<Func<TDataModel, bool>>(
        Expression.Equal(
            keySelector.Body,
            Expression.Constant(id)
        ), 
        keySelector.Parameters.Single()
    );
}
专用表达式GetByIdSelector(TKey id)
{
var keySelector=keySelector;
返回表达式.Lambda(
表达式。相等(
按键选择器。主体,
表达式.常量(id)
), 
keySelector.Parameters.Single()
);
}
我可能会做的是修复KeySelector属性中的代码,以使用固定值,从而使检索到的值始终是同一实例

例如:

private static readonly Expression<Func<User, int>> _keySelector = u => u.UserID;

protected override Expression<Func<User, int>> KeySelector
{
    get { return _keySelector; }
}
私有静态只读表达式_keySelector=u=>u.UserID;
受保护的重写表达式键选择器
{
获取{return\u keySelector;}
}

如果你这样做的话-你的GetByIdSelector旧代码实际上并不比我上面的版本差。

是不是
TDataModel
基类的类型参数?我花了一个小时左右的时间试图弄明白这一点。非常感谢。
private static readonly Expression<Func<User, int>> _keySelector = u => u.UserID;

protected override Expression<Func<User, int>> KeySelector
{
    get { return _keySelector; }
}