【问题标题】:C# Multiple Generic List<t> - Combining Them? [duplicate]C# 多个通用列表<t> - 组合它们? [复制]
【发布时间】:2009-09-30 09:26:00
【问题描述】:

场景:

我有一个通用的审核列表和一个通用的 AuditImage 列表。这两个列表是从数据库表中编译的。因此,一个 AuditImage 可以进行许多审核。正如您将在下面看到的,表映射到的类在数据库中时通过外键关系“ImageID”连接,但是一旦将数据提取到代码中的列表中,就没有“物理连接”了。

数据库表映射到的类:

public class AuditImage
{
    public Guid ImageID { get; set; }
    public string LowResUrl { get; set; }
}

public class Audit
{
    public Guid AuditID { get; set; }
    public Guid ImageID { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public string Comment { get; set; }
}

问题:

我现在想通过从每个列表中提取数据并将“Audit.ImageID == AuditImage.ImageID”上的数据组合到一个新列表中来编译一个“Trail”对象列表。

public class Trail
{
    public Guid ImageID { get; set; }
    public DateTime CreatedDate { get; set; }
    public string CreatedBy { get; set; }
    public string Comment { get; set; }
    public string LowResUrl { get; set; }
}

(上面基本上结合了“LowResUrl”字段与基于 ImageID 相同的每个审核。)

问题:

我该怎么做呢!?我曾考虑过使用 foreach 循环和 linq 来创建一个新的跟踪对象列表,但我不太清楚我将如何去做?!

我们将不胜感激。

【问题讨论】:

  • 这从一开始就带有糟糕设计的味道。为什么要将类与 ID 关联,而不是将 AuditImage 实例放到 Audit 实例中?
  • 令人讨厌的 Silverlight 应用程序设计与凌乱的服务器端代码......

标签: c# list generic-list


【解决方案1】:

你可以这样做


var trails = from audit in audits
   join image in auditImages on audit.ImageId equals image.ImageId
   select new Trail { ImageID = audit.ImageId, CreatedDate = audit.CreatedDate,
                      CreatedBy = audit.CreatedBy, Comment = audit.Comment,
                      LowResUrl = image.LowResUrl };

【讨论】:

    【解决方案2】:

    在 List 上尝试 Intersect 扩展方法:http://msdn.microsoft.com/en-us/library/bb910215.aspx

    我还认为你应该审查你的设计并引入一个通用接口 IAudi 或类似的东西。

    【讨论】:

    • intersect 应该如何解决这个问题?
    【解决方案3】:

    这可以工作.......

    public List<JobImageAudit> CombineForAuditTrail()
            {
                var result = from a in auditList
                             join ai in imageList
                             on a.ImageID equals ai.ImageID
                             //into ait // note grouping        
                             select new JobImageAudit
                             {
                                 JobID = a.JobID,
                                 ImageID = a.ImageID.Value,
                                 CreatedBy = a.CreatedBy,
                                 CreatedDate = a.CreatedDate,
                                 Comment = a.Comment,
                                 LowResUrl = ai.LowResUrl,
    
                             };
                return result.ToList();
            }
    

    【讨论】:

      【解决方案4】:

      我可能会使用扩展方法,只是因为我不太容易使用 linq:

      IEnumerable<Trail> trailList = auditImageList.Join(
        auditList, 
        auditImageItem => auditImageItem.ImageId, 
        auditItem => auditItem.ImageId,
        (auditImageItem, auditItem) =>  new Trail() 
        {  
          LowResUrl = auditImageItem.LowResUrl,
          ImageID = auditImageItem.ImageId, 
          CreatedDate = auditItem.CreatedDate,
          CreatedBy = auditItem.CreatedBy, 
          Comment = auditItem.Comment,
        });
      

      【讨论】:

        【解决方案5】:

        这将解决问题.. from var 查询只需添加到循环中的跟踪对象

            var query = from auditImage in AuditImageList 
            join audit in AuditList 
        on auditImage.ImageID equals audit.ImageID 
        select new { ImageID= auditImage.ImageID, CreatedDate = audit.CreatedDate, CreatedBy = audit.CreatedBY, Comment = audit.Comment , LowResUrl = auditImage.LowResUrl }; 
        
        foreach (var trail in query) { //Assign Values to trail object and add to list of trails }
        

        【讨论】:

        • 为什么不直接创建 Trails?
        【解决方案6】:

        取决于你想要什么:

        内连接(如果有Audit,只显示AuditImage):

        var innerJoin = from image in images
                        join audit in audits on image.ImageID equals audit.ImageID
                        select new { image.ImageID, AuditImageId = audit.ImageID };
        

        左连接(显示AuditImage,即使它没有Audit):

        var leftJoin = from image in images
                       join audit in audits on image.ImageID equals audit.ImageID
                       into auditCats
                       from auditCat in auditCats.DefaultIfEmpty(new Audit())
                       select new { image.ImageID, AuditImageId = auditCat.ImageID };
        

        【讨论】:

          【解决方案7】:

          至少有两种选择。

          首先是做简单的连接:

          var trails = Audits.Join(Images, a => a.ImageID, i => i.ImageID, (a, i) =>
              new Trail
              {
                  Comment = a.Comment,
                  CreatedBy = a.CreatedBy,
                  CreatedDate = a.CreatedDate,
                  ImageID = a.ImageID,
                  LowResUrl = i.LowResUrl
              });
          

          二是使用子查询:

          var trails = Audits.Select(a =>
              new Trail
              {
                  Comment = a.Comment,
                  CreatedBy = a.CreatedBy,
                  CreatedDate = a.CreatedDate,
                  ImageID = a.ImageID,
                  LowResUrl = Images.Single(i => i.ImageID == a.ImageID).LowResUrl
              });
          

          如果 ImageID 是唯一的,两者都应该可以正常工作,但我个人更喜欢子查询,因为它看起来比连接更自然。

          【讨论】:

            猜你喜欢
            • 2023-04-05
            • 1970-01-01
            • 1970-01-01
            • 2014-08-22
            • 2020-10-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-10-17
            相关资源
            最近更新 更多