4

我使用与其他人类似的方法将我的 LINQ 对象保存在我的 LINQ 数据提供程序中并返回 IQueryable 以允许过滤等。这适用于通过其 ID 或其他属性过滤简单对象,但我遇到了问题连接由其他子对象组成的表对象

    //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)
             };

coreDB.Positions 是我的 Linq Position 对象,我返回一个 DTO Position,它由 User、OrgUnit 和 Role 组成(基础表是一个带有 UserID、RoleID 和 OrgUnitID 的连接表)

我遇到的问题是,当我尝试在 Iqueryable 上添加过滤器时,我收到一条 SQL 错误,提示我的 DTO.User 对象没有可用的翻译

public static IQueryable<Position> WithUserID(this IQueryable<Position> query, int userID)
    {
        return query.Where(p => p.User.ID == userID);
    }

我完全不知道如何解决这个问题,因为我所有的谷歌结果似乎都是与直接使用生成的 LINQ 对象的人一起工作的

关于如何完成这项工作的任何想法,或者我在这里做错了什么?

谢谢

4

3 回答 3

1

Linq2SQL 只理解设计器生成的对象。嗯,这并不完全正确,但足够接近。

因此,当您针对 Linq2SQL 对象编写 Linq 查询时,查询将在查询实际执行时转换为有效 SQL,而不是在编写时。由于您的 DTO 对象不是 Linq2SQL 对象,因此 Linq2SQL 将不知道如何创建正确的 SQL。

如果你想以这种方式保持你的分离,你必须找到一种方法来执行你的查询,只涉及 Linq2SQL 对象,并且只将结果映射到你的 DTO。

也许您可以将查询方法重写为:

更新:参数必须是 type Expression<>,并且没有必要返回一个IQueryable<>. 感谢弗雷迪指出。

public IEnumerable<DTO.Position> FindPositions(Expression<Func<Position, bool>> criteria)
{
    return from p in coreDB.Positions
           where criteria.Invoke(p)
           select new DTO.Position
                      {
                          User = new DTO.User(p.User.id, p.User.username, p.User.firstName, p.User.lastName,
                                       p.User.email, p.User.isActive),
                          Role = new DTO.Role(p.Role.id, p.Role.name, p.Role.isActive),
                          OrgUnit = new DTO.OrgUnit(p.OrgUnit.id, p.OrgUnit.name, p.OrgUnit.isActive)
                      };
}
于 2009-03-04T20:09:11.687 回答
1

我已经能够使用类似的方法成功地工作:

var courses = from c in Map(origCourses)
where !expiredStatuses.Contains(c.Status)
select c;

地图有:

    select new UserCourseListItem
    {
        CourseID = c.CourseID,
        CourseName = cm.CourseName,
        CourseType = c.CourseType.Value
        ...

如何尝试使用这种类型的初始化(而不是构造函数)。

附言。这是一个工作应用程序的一部分,expiredStatuses 甚至与一个复杂的表达式有关。

更新 1:这与提到的场景类似,因为:

  • Map 正在返回一个 IQueryable,它是一个 POCO 对象。
  • 在调用返回带有 POCO 对象的 IQueryable 的 Map 方法后,我正在对其应用过滤器。
于 2009-03-04T20:17:35.897 回答
1

I ended up not using filters for my complex queries. Instead, I added methods to the repository for the more complex query requirements. I feel this will make the system easier to understand and hence maintain.

于 2009-03-09T17:39:12.397 回答