C# 使用实体框架创建动态查询
我想知道使用实体框架和linq创建动态查询的最佳方法是什么 我想创建一个具有许多排序和筛选参数(超过50个)的服务。我将从gui中获取对象,这些将在其中填写。。。查询将从单个服务方法执行C# 使用实体框架创建动态查询,c#,linq,entity-framework,entity-framework-4,C#,Linq,Entity Framework,Entity Framework 4,我想知道使用实体框架和linq创建动态查询的最佳方法是什么 我想创建一个具有许多排序和筛选参数(超过50个)的服务。我将从gui中获取对象,这些将在其中填写。。。查询将从单个服务方法执行 我环顾四周,发现我可以动态创建一个字符串,该字符串可以在方法末尾执行。我不太喜欢这种方式。有更好的方法吗?最好使用compile check键入safe?您可以研究使用WCF数据服务创建服务,并动态创建URI以查询您的实体模型。我知道的唯一其他方法是基于您的筛选值构建IQueryable public
我环顾四周,发现我可以动态创建一个字符串,该字符串可以在方法末尾执行。我不太喜欢这种方式。有更好的方法吗?最好使用compile check键入safe?您可以研究使用WCF数据服务创建服务,并动态创建URI以查询您的实体模型。我知道的唯一其他方法是基于您的筛选值构建IQueryable
public List<Contact> Get(FilterValues filter)
{
using (var context = new AdventureWorksEntities())
{
IQueryable<Contact> query = context.Contacts.Where(c => c.ModifiedDate > DateTime.Now);
if (!string.IsNullOrEmpty(filter.FirstName))
{
query = query.Where(c => c.FirstName == filter.FirstName);
}
if (!string.IsNullOrEmpty(filter.LastName))
{
query = query.Where(c => c.LastName == filter.LastName);
}
return query.ToList();
}
}
公共列表获取(FilterValues筛选器)
{
使用(var context=new AdventureWorksEntities())
{
IQueryable query=context.Contacts.Where(c=>c.ModifiedDate>DateTime.Now);
如果(!string.IsNullOrEmpty(filter.FirstName))
{
query=query.Where(c=>c.FirstName==filter.FirstName);
}
如果(!string.IsNullOrEmpty(filter.LastName))
{
query=query.Where(c=>c.LastName==filter.LastName);
}
返回query.ToList();
}
}
您可以一步一步地编写一个IQueryable
。假设您有一个FilterDefinition
类,该类描述用户希望如何筛选
public class FilterDefinition
{
public bool FilterByName { get; set; }
public string NameFrom { get; set; }
public string NameTo { get; set; }
public bool FilterByQuantity { get; set; }
public double QuantityFrom { get; set; }
public double QuantityTo { get; set; }
}
。。。然后您可以像这样构建一个查询:
public IQueryable<SomeEntity> GetQuery(FilterDefinition filter)
{
IQueryable<SomeEntity> query = context.Set<SomeEntity>();
// assuming that you return all records when nothing is specified in the filter
if (filter.FilterByName)
query = query.Where(t =>
t.Name >= filter.NameFrom && t.Name <= filter.NameTo);
if (filter.FilterByQuantity)
query = query.Where(t =>
t.Quantity >= filter.QuantityFrom && t.Quantity <= filter.QuantityTo);
return query;
}
public IQueryable GetQuery(过滤器定义过滤器)
{
IQueryable query=context.Set();
//假设在筛选器中未指定任何内容时返回所有记录
if(filter.FilterByName)
query=query.Where(t=>
t、 Name>=filter.NameFrom&&t.Name
t、 Quantity>=filter.QuantityFrom&&t.Quantity我创建了一个可以帮助您的。它支持统一的API来查询和排序已知字段和动态字段:
//Filter on known fields
var keyboard = Query<Product>.Create(p=>p.Category=="Keyboard");
var keyboards = repository.Get(keyboard);
//Or filter on dynamic fields
var filter = Query<Product>.Create("Rating", OperationType.GreaterThan, 4)
var filteredKeyboards = repository.Get(filter);
//You can also combine two queries togather
var filterdKeyboards2 = repository.Get(keyboard.And(filter))
//Order it on known fields
var orderedKeyboard = keyboard.OrderBy(o=>o.Asc(p=>p.Name));
var orderedKeyboards = repository.Get(orderedKeyboard);
//Or order by on dynamic fields
var userOrdering = keyboard.OrderBy(o=>o.Asc("Name"));
var orderedKeyboards2 = repository.Get(userOrdering);
//对已知字段进行筛选
var keyboard=Query.Create(p=>p.Category==“keyboard”);
var keyboards=repository.Get(键盘);
//或在动态字段上进行筛选
var filter=Query.Create(“评级”,OperationType.GreaterThan,4)
var filteredKeyboards=repository.Get(过滤器);
//您还可以将两个查询组合在一起
var filterdKeyboards2=repository.Get(keyboard.And(filter))
//在已知字段上订购
var orderedKeyboard=keyboard.OrderBy(o=>o.Asc(p=>p.Name));
var orderedKeyboards=repository.Get(orderedKeyboards);
//或在动态字段上按顺序排序
var userOrdering=keyboard.OrderBy(o=>o.Asc(“Name”);
var orderedKeyboards2=repository.Get(userOrdering);
我不知道您正在获取的搜索对象/DTO,但您可以轻松创建一个通用搜索对象/DTO,并可以用几行代码将其映射到查询对象。我过去在WCF服务中使用过它,它对我非常有用。谢谢,但这是如何工作的?这不是从数据库中提取所有数据,然后逐步执行吗tep将其缩小到所需的数据集???@t-edd:不,它利用了延迟执行
()。这意味着上面示例中组成的IQueryable
只是一个描述如何过滤数据的查询表达式。查询的实际执行根本不在示例中。您可以通过对IQueryable
应用“贪婪”操作符来执行查询,例如query.ToList()
。此时(而不是更早的时候),查询表达式被转换为SQL并发送到服务器。这不是很好,因为它假设某个实体
具有名称和数量字段,所以这只是半动态的。有没有办法动态定义和或或呢?它也不允许动态条件可选运算符,例如,如果您希望动态地允许用户按“成本>10”或“成本<10”进行筛选,是的,但这是否有效的性能明智?何时执行select?最后调用ToList()时?假设我有非常大的数据集……不,这不是性能问题,因为它使用延迟执行只查询一次。