C# 创建数据库集<;T>;从表达式创建动态查询服务
我正在尝试使用实体框架创建一个动态查询服务 我的方法是以某种方式创建一个轻型客户端,用于通过DTO创建查询,生成一个C# 创建数据库集<;T>;从表达式创建动态查询服务,c#,entity-framework,repository,C#,Entity Framework,Repository,我正在尝试使用实体框架创建一个动态查询服务 我的方法是以某种方式创建一个轻型客户端,用于通过DTO创建查询,生成一个IQueryable或一个表达式,然后通过网络将该查询\表达式发送到一个执行服务,该服务将IQueryable\表达式转换为SQL,运行它并返回一个IEnumerable 我的想法是使用Enumerable.Empty.AsQueryable()来创建查询,但是当我需要执行查询时,我需要将它们转换为SQL的能力,这就是实体框架应该如何帮助我的 实体框架使用实现IQueryable的
IQueryable
或一个表达式
,然后通过网络将该查询\表达式发送到一个执行服务,该服务将IQueryable
\表达式
转换为SQL,运行它并返回一个IEnumerable
我的想法是使用Enumerable.Empty.AsQueryable()
来创建查询,但是当我需要执行查询时,我需要将它们转换为SQL的能力,这就是实体框架应该如何帮助我的
实体框架使用实现IQueryable
的类(如DbSet
和DbQuery
)实现了它的魔力
我可以创建一个客户机,它将使用实体框架dummyDbContext
创建IQueryable的
,因此我基本上可以创建查询,并能够在客户机上从查询中生成SQL
我尝试在框架之间混合使用实体框架,从我的IQueryable
生成SQL,然后使用Dapper执行它,但是当涉及嵌套导航属性时,它会变得复杂,我仍然希望能够在我的服务上使用自定义表达式的
修改查询因此,在客户机上创建查询并向服务发送SQL并不是一个真正适合我的解决方案 是否有任何方法可以从
表达式创建DbSet
?或者以某种方式“序列化”一个DbSet
?
是否有其他推荐的框架可以帮助我实现此功能
编辑->以下是我试图实现的一些PSEDOO代码:
客户:
var query = QueryCreator
.Get<MyDto>()
.Include(d => d.MySonDto)
.Where(d => d.IsActive)
.OrderBy(d => d.MySonDto.Date)
.Take(10);
var result = service.Query(query); // or `service.Query(query.Expression);`
var query=QueryCreator
.Get()
.Include(d=>d.MySonDto)
.其中(d=>d.IsActive)
.OrderBy(d=>d.MySonDto.Date)
.采取(10);
var result=service.Query(Query);//或`service.Query(Query.Expression)`
我的服务需要以某种方式接收查询,将其转换为SQL,执行它并对数据库运行它
现在我考虑使用实体框架进行翻译,现在我的主要问题是如何序列化IQueryable
或表达式
,并在服务上从中创建DbSet
?
(DbSet.Parse(expression)
很好:-)假设您知道T
(根据注释),您可以使用CreateQuery
使用收到的表达式创建查询:
var context = new YourContext();
var data = context.Set<T>()
.AsQueryable()
.Provider.CreateQuery(yourReceivedExpressionOfTEntity)
.ToList();
var context=newyourcontext();
var data=context.Set()
.AsQueryable()
.Provider.CreateQuery(YourReceivedPressionOftEntity)
.ToList();
我在尝试类似于您在过去提出的方法时遇到了巨大的麻烦,尤其是在序列化泛型和表达式树方面。您是否考虑过在您的服务层上公开OData端点?例如@ChrisPickford-我想到了一个较弱的OData解决方案。我仍然在尝试这条路径,因为我有一些额外的需求,我没有在这里指定。你能添加一个伪代码示例吗?@CamiloTerevinto-我添加了一些伪代码。希望这有助于理解我的问题。您能使DbContext
静态类型化(即添加已知实体)还是必须完全通用(即任何数据库/表)?感谢您的回复。我可以使用newMyDbContext().Set()
以更简单的方式获取DbSet
。我不需要第二个代码部分,因为DbSet
是IQueryable
。如果我不想在我的代码中使用DbSet
跟踪,我总是可以强制转换它。我的问题是如何发送查询并从查询\表达式创建DbSet
。@AmirPopovichSet()
如果您不知道t
是什么,那么它就不起作用。您不需要创建DbSet
,您需要将表达式应用于DbSet
(至少从您的问题中可以理解这一点)我知道T是什么,即使我将T作为一种类型接收,我也可以始终使用MakeGenericMethod
或其他反射解决方案来检索DbSet
。DbSet
仅用于对数据库进行更改,用于使用IQueryable
的查询,因此,我并不确定您现在要问的是一个DbSet
是一个实体框架类,它实现了IQueryable
和其他接口。您可以将DbSet
强制转换为IQueryable
。基本上,DbSet(或它继承的DbQuery)提供了将查询转换为SQL的功能。这是使用从Enumerable.Empty().AsQueryable
创建的IQueryable
无法实现的。