Linq to sql Linq到SQL DTO和复合对象
我正在使用与其他人类似的方法将我的LINQ对象保留在我的LINQ数据提供程序中,并返回IQueryable以允许筛选等。这对于根据简单对象的ID或其他属性筛选简单对象很有效,但我遇到了由其他子对象组成的联接表对象的问题Linq to sql Linq到SQL DTO和复合对象,linq-to-sql,dto,separation-of-concerns,Linq To Sql,Dto,Separation Of Concerns,我正在使用与其他人类似的方法将我的LINQ对象保留在我的LINQ数据提供程序中,并返回IQueryable以允许筛选等。这对于根据简单对象的ID或其他属性筛选简单对象很有效,但我遇到了由其他子对象组成的联接表对象的问题 //CoreDBDataContext db = coreDB; public IQueryable<DTO.Position> GetPositions() { return from p in coreDB.Positions
//CoreDBDataContext db = coreDB;
public IQueryable<DTO.Position> GetPositions() {
return from p in coreDB.Positions
select new DTO.Position
{
DTO.User = new DTO.User(p.User.id,p.User.username, p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
DTO.Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
DTO.OrgUnit = new DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
};
//CoreDBDataContext db=coreDB;
公共IQueryable GetPositions(){
从coreDB.位置的p返回
选择新的DTO位置
{
DTO.User=新的DTO.User(p.User.id,p.User.username,p.User.firstName,p.User.lastName,p.User.email,p.User.isActive),
DTO.Role=新的DTO.Role(p.Role.id,p.Role.name,p.Role.isActive),
DTO.OrgUnit=新的DTO.OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
};
Positions是我的Linq Position对象,我返回一个DTO Position,它由用户、OrgUnit和角色组成(底层表是一个带有UserID、RoleID和OrgUnitID的联接表)
我遇到的问题是,当我尝试在iQueryTable上添加过滤器时,我得到一个SQL错误,表示没有可用于我的DTO.User对象的转换
public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
{
return query.Where(p => p.User.ID == userID);
}
publicstaticiqueryable with userID(此IQueryable查询,int-userID)
{
返回query.Where(p=>p.User.ID==userID);
}
我完全不知道如何着手解决这个问题,因为我所有的谷歌搜索结果似乎都是与直接处理生成的LINQ对象的人一起工作的
有没有想过如何让这一切顺利进行,或者我在这里做了什么完全错误的事情
谢谢Linq2SQL只理解设计器生成的对象。嗯,这并不完全正确,但已经足够接近了 因此,当您针对Linq2SQL对象编写Linq查询时,查询将在实际执行时转换为有效的SQL,而不是在编写时。由于您的DTO对象不是Linq2SQL对象,Linq2SQL将不知道如何创建正确的SQL 如果希望以这种方式保持分离,则必须找到一种只使用Linq2SQL对象执行查询的方法,并且只将结果映射到DTO 也许您可以将查询方法重写为: 更新:参数的类型必须为
表达式
,无需
返回一个IQueryable
。感谢
弗雷迪指出
public IEnumerable FindPositions(表达式条件)
{
从coreDB.位置的p返回
where-criteria.Invoke(p)
选择新的DTO位置
{
User=new DTO.User(p.User.id、p.User.username、p.User.firstName、p.User.lastName、,
p、 User.email,p.User.isActive),
Role=新的DTO.Role(p.Role.id、p.Role.name、p.Role.isActive),
OrgUnit=新数据到OrgUnit(p.OrgUnit.id,p.OrgUnit.name,p.OrgUnit.isActive)
};
}
我已经能够成功地使用类似的方法:
var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;
其中Map有:
select new UserCourseListItem
{
CourseID = c.CourseID,
CourseName = cm.CourseName,
CourseType = c.CourseType.Value
...
用那种类型的初始化(而不是构造函数)试试怎么样
这是工作应用程序的一部分,ExpiredStatus甚至与复杂表达式相关
更新1:这与上述场景类似,因为:
- Map正在返回一个IQueryable,它是一个POCO对象
- 调用Map方法返回一个带有POCO对象的IQueryable之后,我对它应用了一个过滤器
select new UserCourseListItem
{
CourseID = c.CourseID,
CourseName = cm.CourseName,
CourseType = c.CourseType.Value
...