C# 使用linq到sql后端通过WCF查询DTO对象
我正在做一个项目,我们需要创建复杂的查询 WCF服务 该服务在后端使用linq to sql,并将查询投影到数据传输对象,如下所示: dbContext.GetQueryable() .Where(x => x.Id == formatId) .Select(x => FormatHelper.PopulateMSFormat(x)) .ToList(); dbContext.GetQueryable() .Where(x=>x.Id==formatId) .Select(x=>FormatHelper.PopulateMSFormat(x)) .ToList(); 我想做的是在客户端指定一个查询,假设我想查询具有某个属性或两个属性的所有格式。 这种风格的东西: var assets = client.QueryForAssets().Where(x => (x.name == "Test" || x == "Arne") && x.doe == "john"); var assets=client.QueryForAssets()。其中(x=>(x.name==“Test”| | x==“Arne”)和&x.doe==“john”); 我知道我不能通过WCF返回IQueryable,但类似的事情可以通过OData服务完成。问题是我必须返回DTO,OData让我很容易绑定到L2S datacontext,它公开了我的数据模型,而不是DTO 那么,有没有一种对DTO序列化查询的好方法可以有效地传播到l2s层呢C# 使用linq到sql后端通过WCF查询DTO对象,c#,sql,wcf,linq,dto,C#,Sql,Wcf,Linq,Dto,我正在做一个项目,我们需要创建复杂的查询 WCF服务 该服务在后端使用linq to sql,并将查询投影到数据传输对象,如下所示: dbContext.GetQueryable() .Where(x => x.Id == formatId) .Select(x => FormatHelper.PopulateMSFormat(x)) .ToList(); dbContext.Ge
我曾考虑编写自己的查询语言,但我发现要构建正确的表达式树作为l2s的谓词是相当困难的,因为没有从DTO到linq类的映射 使用
OData
服务,您不必直接返回数据库实体。您只需以可查询格式返回任何DTO
。然后,借助LINQ的Select()
方法,您只需在服务查询之前将任何数据库实体转换为DTO
:
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; }
}
公共类数据模型
{
公共数据模型()
{
使用(var dbContext=newdatabasecontext())
{
Employees=来自dbContext.Employee中的e
选择新员工待办事项
{
ID=e.EmployeeID,
部门ID=e.部门ID,
AddressID=e.AddressID,
FirstName=e.FirstName,
LastName=e.LastName,
StreetNumber=e.Address.StreetNumber,
StreetName=e.Address.StreetName
};
}
}
///返回员工列表。
公共IQueryable雇员{get;private set;}
}
您现在可以轻松地将其设置为OData服务,如下所示:
public class EmployeeDataService : DataService<DataModel>
公共类EmployeeDataService:DataService
有关完整的实现细节,请参阅关于该主题的优秀文章。一旦你掌握了OData服务,它实际上非常强大。我相信你可以使用OData服务返回DTO 看一看。特别是“公开数据库的转换”部分。您可以将实体对象展平为DTO,并让客户机针对该DTO模型运行查询
这就是你正在寻找的东西吗?如果你有很长的复杂实体,那么手工创建投影就是一场噩梦<代码>自动映射无法工作,因为LINQ无法将其与IQueryable结合使用 这是一个完美的解决方案: 它将“神奇地”为您生成投影,并使您能够基于DTO(数据传输对象)类运行oData查询
注意:这篇文章是几年前写的,到目前为止,
AutoMapper
可能已经内置了这样的功能。我只是没有时间,我现在自己检查一下。上述参考文章的灵感来源于AutoMapper本身的作者——因此,现在可能包含一些改进版本。总体概念似乎很棒,这个版本对我来说很好。听起来是个不错的解决方案,但我无法让它工作。我怀疑这与我使用L2S并没有解决至少两个问题有关。我不能使用helper方法,因为上下文是包装在using中的,所以在查询集合时它将被释放。使用L2S或EF并不重要。您可以汇集来自任何源的数据。由于OData服务对象是“按请求”创建的,因此使用using
语句是正确的方法,因为DataModel
类实例将随请求一起创建和销毁。我不同意using语句,只要datacontext超出范围,即Get()之前,就会调用dispose方法有人打电话来。
[Queryable]
public IQueryable<DatabaseProductDTO> GetDatabaseProductDTO(ODataQueryOptions<DatabaseProductDTO> options)
{
// _db.DatabaseProducts is an EF table
// DatabaseProductDTO is my DTO object
var projectedDTOs = _db.DatabaseProducts.Project().To<DatabaseProductDTO>();
var settings = new ODataQuerySettings();
var results = (IQueryable<DatabaseProductDTO>) options.ApplyTo(projectedDTOs, settings);
return results.ToArray().AsQueryable();
}
/odata/DatabaseProductDTO?$filter=FreeShipping eq true