在linq中连接3个表,从两个表中获取所有条目

时间:2012-08-22 13:57:32

标签: c# linq join

我有3张桌子

  • 项目表
  • 产品表
  • 更新表

产品表包含项目中的不同产品,更新表包含对各种产品的更新,并包含对执行此操作的用户的引用。

基本上我想要的是有一个查询,它返回所有产品(因为产品与项目是多对一的关系),按照我们上次由当前登录用户更新的日期排序。

这是我目前的查询:

IEnumerable<ProjectProduct> list =
       from joined in
           (from product in db.GetTable<Product>()
            join project in db.GetTable<Project>()
            on product.ProjectId equals project.ID
            select new { product, project })
       join projectupd in db.GetTable<ProjectUpdate>()
       on joined.product.ID equals projectupd.ProductID
       where projectupd.CreatedBy == ParamUser
       orderby projectupd.LastUpdate
       select new ProjectProduct(joined.project, joined.product);

但是,我得到的结果只是更新表中的条目,而不是所有现有产品。我知道“where”子句使它只选择由特定用户创建的更新,所以我在正确的轨道上,但我尝试了一些使查询成功的事情,但没有运气。

有人建议如何获得理想的结果吗?

1 个答案:

答案 0 :(得分:1)

这是一个有点冗长的答案,它使用方法链语法,但我确实认为它符合您的要求:

var products = db.GetTable<Product>();
var projects = db.GetTable<Project>();
var projectUpdates = db.GetTable<ProjectUpdate>();

var latestProjectUpdatesForUser = projectUpdates
    .Where(x => x.CreatedBy == paramUser)
    .GroupBy(x => x.ProductId)
    .Select(g => g.OrderByDescending(x => x.LastUpdate).First());

var list = products
    .Join(
        projects,
        product => product.ProjectId,
        project => project.Id,
        (product, project) => new
            {
                Product = product,
                Project = project,
                Update = latestProjectUpdatesForUser.FirstOrDefault(u => u.ProductId == product.Id)
            }
    )
    .OrderByDescending(x => x.Update != null ? (DateTime?)x.Update.LastUpdate : null)
    .ThenBy(x => x.Project.Id)
    .ThenBy(x => x.Product.Id)
    .Select(x => new ProjectProduct { Project = x.Project, Product = x.Product});

利用DateTime?可排序且null值在使用OrderByDescending时最后结束的事实。