【问题标题】:Linq Selector with dynamic property name具有动态属性名称的 Linq 选择器
【发布时间】:2018-02-08 15:11:23
【问题描述】:

我有一个IQueryable<TEntity>,其中TEntity 是另一个类BaseEntity<TKey, TUId>

因为BaseEntity<TKey, TUid>有两个泛型参数,如果要从IQueryable中选择一列,必须提前知道TKeyTUId的类型。

但我也知道BaseEntity<TKey, TUId> 将始终有一个名为UId 的数字属性,这就是我需要得到的。

我想要实现的是类似于下面的代码,我可以在其中定义一个选择器变量,其中包含我希望查询选择的属性,但是是动态的。就像在字符串变量中设置这个名称一样。

var selector = nameof(BaseEntity<,>.UId);
IQueryable<TEntity> query = GetQueryByPrimaryKey();
var entityUId = Convert.ToInt64(query.Select(selector).Single());

TEntity 中限制只接受BaseEntity&lt;TKey, TUId&gt; 不是一种选择,因为我没有每个参数的类型,我需要定义所有可能性。

有没有办法创建一个动态的 lambda 选择器来指示我想要获取的属性的字符串名称?

主要目标是使用主键对数据库进行单次查询,只选择一个字段(映射的UId列)以提高性能。

我已经阅读了一些解决方案,一些指出了 Dynamic Query,但我更喜欢原生解决方案。

【问题讨论】:

    标签: c# linq dynamic lambda selector


    【解决方案1】:

    看起来您想创建一个动态表达式并在其上调用Select

    private Expression<Func<BaseEntity<TKey, TUId>, long>> CreateUIdExpression<TKey,
     TUId>()
    {
        var param = Expression.Parameter(typeof(BaseEntity<TKey, TUId>));
        var memberExpression = Expression.Property(param, "UId");
        var expr = Expression.Lambda<Func<BaseEntity<TKey, TUId>, long>>(memberExpression, param);
    
        return expr;
    }
    

    用法:

    var newQuery = query.Select(CreateUIdExpression<TKey, TUId>());
    

    顺便说一句,我假设 UId 很长。

    【讨论】:

    • 效果很好,我实际上将 BaseEntity 更改为 T 可重用。我遇到的唯一问题是类型并不总是很长,它可以是长、整数、短、字节。我会尝试解决这个问题。谢谢!
    猜你喜欢
    • 2020-11-03
    • 2015-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-18
    相关资源
    最近更新 更多