我正在一个项目中,我们需要针对WCF服务创建复杂的查询。
该服务在后端使用linq to sql并将查询投影到数据传输对象,如下所示:
dbContext.GetQueryable() 哪里(x => x.Id == formatId) 选择(x => FormatHelper.PopulateMSFormat(x)) .ToList();
我想做的是在客户端指定一个查询,可以说我要查询具有某个属性或其中几个属性的所有格式。这种风格的东西:
var asset = client.QueryForAssets()。Where(x =>(x.name ==“ Test” || x ==“ Arne”)&& x.doe ==“ john”);
我知道我无法通过WCF返回IQueryable,但是可以使用OData服务来完成类似的工作。问题是我必须返回DTO,而OData让我很容易地绑定到L2S-datacontext,这将暴露我的数据模型,而不是DTO。
那么,有没有一种对DTO进行序列化查询的好方法,该查询将有效地传播到l2s层?
我考虑过要编写自己的查询语言,但是我发现很难构建正确的表达式树作为l2s的谓词,因为没有从DTO到linq类的映射。
使用OData服务,您不必直接返回数据库实体。您可以简单地DTO以可查询的格式返回任何内容。然后,借助LINQ的Select()方法,您可以DTO在服务查询之前将任何数据库实体简单地转换为:
OData
DTO
Select()
public class DataModel { public DataModel() { using (var dbContext = new DatabaseContext()) { Employees = from e in dbContext.Employee select new EmployeeDto { ID = e.EmployeeID, DepartmentID = e.DepartmentID, AddressID = e.AddressID, FirstName = e.FirstName, LastName = e.LastName, StreetNumber = e.Address.StreetNumber, StreetName = e.Address.StreetName }; } } /// <summary>Returns the list of employees.</summary> public IQueryable<EmployeeDto> Employees { get; private set; } }
您现在可以轻松地将其设置为OData服务,如下所示:
public class EmployeeDataService : DataService<DataModel>
有关完整的实现细节,请参见此主题的出色文章。一旦掌握了OData服务,它们实际上就会非常强大。