C# 在运行时将类型传递给IQueryable

C# 在运行时将类型传递给IQueryable,c#,.net,entity-framework,linq,C#,.net,Entity Framework,Linq,是否可以在运行时将类型传递给IQueryable以实现 像 稍后我需要使用这个测试变量来动态查询数据 另外,请建议解决此问题的任何替代方案。通过反射可以实现您的要求,但可维护性将受到限制。您最好为您的类型创建一个共享接口并编写一个泛型方法,如下所示: interface IMyInterface { string SomeProperty {get;set;} } class MyClass : IMyInterface { public string SomeProperty

是否可以在运行时将类型传递给IQueryable以实现

稍后我需要使用这个测试变量来动态查询数据


另外,请建议解决此问题的任何替代方案。

通过反射可以实现您的要求,但可维护性将受到限制。您最好为您的类型创建一个共享接口并编写一个泛型方法,如下所示:

interface IMyInterface
{
    string SomeProperty {get;set;}
}

class MyClass : IMyInterface
{
    public string SomeProperty {get;set;}
}

IQueryable<T> SomeMethod<T>() where T : IMyInterface, new()
{
    var result = new List<T>() { 
        new T() { SomeProperty = "a"}, 
        new T() { SomeProperty = "b"} 
    };
    return result.AsQueryable();
}
接口IMyInterface
{
字符串SomeProperty{get;set;}
}
类MyClass:IMyInterface
{
公共字符串SomeProperty{get;set;}
}
IQueryable SomeMethod(),其中T:IMyInterface,new()
{
var result=新列表(){
新的T(){SomeProperty=“a”},
新的T(){SomeProperty=“b”}
};
返回结果。AsQueryable();
}
因此,对泛型方法的调用可能是:

var temp = SomeMethod<MyClass>();
var temp=SomeMethod();

有很多方法可以通过反射实现您的要求,但可维护性会受到限制。您最好为您的类型创建一个共享接口并编写一个泛型方法,如下所示:

interface IMyInterface
{
    string SomeProperty {get;set;}
}

class MyClass : IMyInterface
{
    public string SomeProperty {get;set;}
}

IQueryable<T> SomeMethod<T>() where T : IMyInterface, new()
{
    var result = new List<T>() { 
        new T() { SomeProperty = "a"}, 
        new T() { SomeProperty = "b"} 
    };
    return result.AsQueryable();
}
接口IMyInterface
{
字符串SomeProperty{get;set;}
}
类MyClass:IMyInterface
{
公共字符串SomeProperty{get;set;}
}
IQueryable SomeMethod(),其中T:IMyInterface,new()
{
var result=新列表(){
新的T(){SomeProperty=“a”},
新的T(){SomeProperty=“b”}
};
返回结果。AsQueryable();
}
因此,对泛型方法的调用可能是:

var temp = SomeMethod<MyClass>();
var temp=SomeMethod();

如果您有所需的
IQueryable
类型的示例,可以使用泛型方法捕获该类型-此方法返回正确类型的null:

public static T NullByExample<T>(this T _) where T : class => (T)null;
或者创建一个
IQueryable
变体-不幸的是,实际上没有一个
IQueryable
等价于
Enumerable。空的

public static IQueryable<T> EmptyQueryByExample<T>(this T _) => Enumerable.Empty<T>().AsQueryable();

var test = EmptyQueryByExample(queryObject);
public static IQueryable EmptyQueryByExample(此T)=>Enumerable.Empty().AsQueryable();
var测试=空QueryByExample(queryObject);

否则,正如前面提到的,你处于反思的世界中,这可能表明你做错了什么。问题是,在这种情况下,您将发现您只能将
test
类型设置为
object
,因为编译器不知道
类型
表示什么,例如
var
是编译时的速记,除非您想使用
动态
(您也不应该这样做).

如果您有所需的
IQueryable
类型的示例,可以使用泛型方法捕获该类型-此方法返回正确类型的null:

public static T NullByExample<T>(this T _) where T : class => (T)null;
或者创建一个
IQueryable
变体-不幸的是,实际上没有一个
IQueryable
等价于
Enumerable。空的

public static IQueryable<T> EmptyQueryByExample<T>(this T _) => Enumerable.Empty<T>().AsQueryable();

var test = EmptyQueryByExample(queryObject);
public static IQueryable EmptyQueryByExample(此T)=>Enumerable.Empty().AsQueryable();
var测试=空QueryByExample(queryObject);

否则,正如前面提到的,你处于反思的世界中,这可能表明你做错了什么。问题是,在这种情况下,你会发现你只能将
test
类型设置为
object
,因为编译器不知道
类型
代表什么,例如
var
是编译时的速记,除非你想使用
动态
(你也不应该这样做)。

不是这样的,不可以。你可以创建一个泛型方法,但没有上下文就无法判断。尝试这样做表明你的程序结构存在更大的问题。您在这里的最终目标是什么?我认为您可以,但是您的服务层变得非常复杂,因为您需要动态地使用存储库(表)映射类型。此外,处理导航属性也变得非常复杂。鉴于大多数IQueryable扩展方法都采用特定类型的表达式,尝试处理可查询属性会很快变得非常混乱。如果您只想让一个queryable返回数据库中的所有实体,这是可能的,但是您可能需要使用动态结果,这同样是混乱的。你要处理多少种类型?你能用另一种方法来做吗?例如,围绕你想要的类型使用一个switch语句?@zander谢谢你的回复,添加了我遇到的问题的详细信息。不是这样,不。你可以创建一个通用方法,但没有上下文就无法判断。尝试这样做表明你的程序结构存在更大的问题。您在这里的最终目标是什么?我认为您可以,但是您的服务层变得非常复杂,因为您需要动态地使用存储库(表)映射类型。此外,处理导航属性也变得非常复杂。鉴于大多数IQueryable扩展方法都采用特定类型的表达式,尝试处理可查询属性会很快变得非常混乱。如果您只想让一个queryable返回数据库中的所有实体,这是可能的,但是您可能需要使用动态结果,这同样是混乱的。你要处理多少种类型?你能用另一种方法来做吗?例如,用一个switch语句来说明你想要什么类型?@zander谢谢你的回复,补充了我遇到的问题的细节。
public static IQueryable<T> EmptyQueryByExample<T>(this T _) => Enumerable.Empty<T>().AsQueryable();

var test = EmptyQueryByExample(queryObject);