使用泛型类属性的LINQ表达式 [英] LINQ expression with generic class properties

查看:104
本文介绍了使用泛型类属性的LINQ表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



由于ID可以是长整型或者是长整型,也可以是长整型

 <$ c我应该一般性地解决它。



我想出了以下内容: $ c> public static IEnumerable< T> GetModified< TId,T>(IQueryable T> objects,TId [] id)其中T:class
{
return objects.Where(j => ids.Contains((TId)j.GetType ().GetProperty( ID)的GetValue(J)));
}

不幸的是我收到了一个例外:


LINQ to Entities不识别方法'System.Object GetValue(System.Object)'方法,并且此方法不能转换为存储表达式。



解决方案

异常是正常的,因为通过反射获取属性显然不能转换为SQL。 / p>

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

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

现在你可以声明你的实体实现 HasId< ;例如,如果 Id 类型为 int ,则int> p>

下一步是修改您的方法,如下所示:

  public static IEnumerable的< T> GetModified< TId,T> 
(IQueryable< T>对象,TId [] id)其中T:class,HasId< TId>
{
return objects.Where(j => ids.Contains(j.Id));

$ / code>

请注意添加的通用限制:其中T:class ,HasId< TId> 。这使您可以编写简化的 j.Id ,它将返回 TId 值,而不是采用反射。 / p>

请注意,我没有运行或测试此代码;这只是一个想法,当我看到你的问题时,我希望它有帮助。



更新:



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

  public static IEnumerable< T> ; GetModified< TId,T> 
(IQueryable< T>对象,TId [] id,表达式< Func< T,TId>> idSelector)
其中T:class
{
return objects.Where j => ids.Contains(idSelector(j)));
}

我在这里完成的是添加 Expression< ; Func< T,TId>> idSelector 参数,该表达式可以返回 T 给定实例的 Id



您可以这样调用方法:

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

(只有第三个参数是新的;现在保留其他参数)。



再一次,我还没有测试过这个工作是否正常,甚至没有编译,因为我在这里没有带有VS的计算机:(。


I would like to pass an IQueryable and an array of ids to a method which filters the IQueryable based on those ids.

As the ids can be either long's or int's it should be solved generically.

I came up with the following:

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)));
}

Unfortunately I'm getting the exception:

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

解决方案

The exception is normal, as getting properties through reflection is something that clearly cannot be translated to SQL.

One thing I would try is to create a generic interface that exposes an Id property of a given type:

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

Now you could declare your entity as implementing HasId<int>, for example, if the Id was of type int.

The next step is to modify your method like so:

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));
}

Note the added generic restriction: where T : class, HasId<TId>. This enables you to write the simplified j.Id, which returns a TId value, instead of resorting to reflection.

Please note that I haven't run or tested this code; it's just an idea that I got when I saw your problem and I hope it helps.

Update:

Here's another possible solution that doesn't require that you declare interfaces or change your classes in any way:

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)));
}

What I've done here is add the Expression<Func<T, TId>> idSelector parameter, an expression that can return the Id of a given instance of T.

You would call the method like that:

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

(only the third parameter being new; keep the others as you have them now).

Again, I haven't tested if this works or even compiles, as I don't have a computer with VS here :(.

这篇关于使用泛型类属性的LINQ表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆