gpt4 book ai didi

c# - 具有泛型类属性的 LINQ 表达式

转载 作者:太空狗 更新时间:2023-10-30 00:25:08 25 4
gpt4 key购买 nike

我想将一个 IQueryable 和一个 ID 数组传递给一个方法,该方法根据这些 ID 过滤 IQueryable。

由于 id 可以是 long 型或 int 型,因此应该一般地解决。

我想到了以下内容:

public static IEnumerable<T> GetModified<TId, T>(IQueryable<T> objects, TId[] ids) where T : class
{
return objects.Where(j => ids.Contains((TId)j.GetType().GetProperty("Id").GetValue(j)));
}

不幸的是我遇到了异常:

LINQ to Entities does not recognize the method 'System.Object GetValue(System.Object)' method, and this method cannot be translated into a store expression.

最佳答案

异常是正常的,因为通过反射获取属性显然无法转换为 SQL。

我会尝试的一件事是创建一个公开 Id 的通用接口(interface)给定类型的属性:

public interface HasId<T> {
T Id { get; set; }
}

现在您可以声明您的实体实现了 HasId<int> ,例如,如果 Id类型为 int .

下一步是像这样修改您的方法:

public static IEnumerable<T> GetModified<TId, T>
(IQueryable<T> objects, TId[] ids) where T : class, HasId<TId>
{
return objects.Where(j => ids.Contains(j.Id));
}

注意添加的通用限制:where T : class, HasId<TId> .这使您能够编写简化的 j.Id ,它返回一个 TId值(value),而不是诉诸反射(reflection)。

请注意,我还没有运行或测试过这段代码;这只是我看到您的问题时的一个想法,希望对您有所帮助。

更新:

这是另一种可能的解决方案,它不需要您以任何方式声明接口(interface)或更改您的类:

public static IEnumerable<T> GetModified<TId, T>
(IQueryable<T> objects, TId[] ids, Expression<Func<T, TId>> idSelector)
where T : class
{
return objects.Where(j => ids.Contains(idSelector(j)));
}

我在这里所做的是添加 Expression<Func<T, TId>> idSelector参数,一个可以返回 Id 的表达式T 的给定实例.

您可以这样调用该方法:

var modified = GetModified(dbObjects, yourIdArray, entity => entity.Id);

(只有第三个参数是新的;保持其他参数不变)。

同样,我还没有测试它是否有效甚至编译,因为我这里没有装有 VS 的计算机:(。

关于c# - 具有泛型类属性的 LINQ 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18930503/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com