2013-05-02 81 views
2

我有以下的LINQ /λ表达式COMMENTSATTACHMENTSRECORDS(这些是表的名称在数据库)相关联。如何解决linq/lambda表达式中的组连接问题?

var comments = repositoryBase.Query<Comments>() 
    .Select(x => x); 

var attachments = repositoryBase.Query<Attachment>() 
    .Where(x => x.DeletedFlag == false) 
    .Select(x => x); 

var recordItems = repositoryBase.Query<Record>() 
    .Where(x => x.DepartmentId == departmentIdId && x.DeletedFlag == false); 

recordItems = recordItems 
    .Where(x => x.Featured == true && (x.PhaseTypeId == 2 || x.PhaseTypeId == 3)); // filtering 

var recordComments = recordItems 
    .GroupJoin(comments, 
     itm => new { a = 1, b = itm.RecordId }, 
     c => new { a = c.TypeId, b = c.Id }, 
     (itm, c) => new { c, itm }) 
    .SelectMany(x => x.c.DefaultIfEmpty(), (x, y) => new 
    { 
     Comments = (y != null) ? true : false, 
     CommentsCount = x.c.Count(), 
     RecordId = x.itm.RecordId, 
     Featured = x.itm.Featured, 
     Id = x.itm.RecordId, 
     PhaseName = x.itm.PhaseType.PhaseName, 
     x.itm.ProductionDate, 
     x.itm.PublishedDate, 
     Title = x.itm.RecordTitle, 
     x.itm.UpdatedDate 
    }).Distinct(); 

其中TYPEID和Id在c => new { a = c.TypeId, b = c.Id }评论哪个组加入(左外连接)领域完成。

var recordAttachments = recordComments 
    .GroupJoin(attachments, 
     itm => new { a = 1, b = itm.RecordId }, 
     at => new { a = at.ContentType, b = at.ContentId }, 
     (itm, at) => new { at, itm}) 
    .SelectMany(x => x.at.DefaultIfEmpty(), (x, y) => new 
    { 
     Attachments = (y != null) ? true : false, 
     AttachmentsCount = x.at.Count(), 
     AttachmentTitle = y.FileName, 
     AttachmentId = (y != null) ? y.AttachmentId : 0, 
     TypeId = (y != null) ? y.ContentType : 0, 
     ItemId = (y != null) ? y.ContentId : 0, 
     Comments = x.itm.Comments, 
     CommentsCount = x.itm.CommentsCount, 
     Featured = x.itm.Featured, 
     Id = x.itm.RecordId, 
     PhaseName = x.itm.PhaseName, 
     x.itm.ProductionDate, 
     x.itm.PublishedDate, 
     Title = x.itm.Title, 
     x.itm.UpdatedDate 
    }).Distinct().ToList(); 

但与去年lambda表达式存在,如果有两个附件对相同的记录,以附件的一条记录被复制(而不是在数据库中,但鉴于)的问题。

如图所示

"Data": [ 
    { 
     "typeid": 1, 
     "typename": "Record Scan", 
     "id": 3071, 
     "title": "Late Outcomes", 
     "publishdate": "3/4/2013", 
     "featured": true, 
     "productiondate": "", 
     "phasename": "Board", 
     "updateddate": "4/29/2013", 
     "updateddateforsorting": "2013-04-29T19:44:29.47", 
     "comments": true, 
     "numofcomments": 4, 
     "attachment": true, 
     "numofattachments": 2, 
     "attachments": [ 
      { 
       "attachmentid": 371, 
       "typeid": 1, 
       "id": 0, 
       "title": "Cardio_David.docx", 
       "name": null, 
       "createddate": "0001-01-01T00:00:00" 
      }, 
      { 
       "attachmentid": 434, 
       "typeid": 1, 
       "id": 0, 
       "title": "blanks in password field.docx", 
       "name": null, 
       "createddate": "0001-01-01T00:00:00" 
      } 
     ] 
    }, 
    { 
     "typeid": 1, 
     "typename": "Record Scan", 
     "id": 3071, 
     "title": "Late Outcomes", 
     "publishdate": "3/4/2013", 
     "featured": true, 
     "productiondate": "", 
     "phasename": "Board", 
     "updateddate": "4/29/2013", 
     "updateddateforsorting": "2013-04-29T19:44:29.47", 
     "comments": true, 
     "numofcomments": 4, 
     "attachment": true, 
     "numofattachments": 2, 
     "attachments": [ 
      { 
       "attachmentid": 371, 
       "typeid": 1, 
       "id": 0, 
       "title": "Cardio_David.docx", 
       "name": null, 
       "createddate": "0001-01-01T00:00:00" 
      }, 
      { 
       "attachmentid": 434, 
       "typeid": 1, 
       "id": 0, 
       "title": "blanks in password field.docx", 
       "name": null, 
       "createddate": "0001-01-01T00:00:00" 
      } 
     ] 
    } 
] 

NB-这是一个简单的数据忽略字段名和值 我已经editted最后一个码recordAttachment作为

var recordAttachment= from rc in recordComments 
             join at in attachments on rc.RecordId equals at.ContentId into ra 
             select new { Comments = rc.Comments, CommentsCount = rc.CommentsCount Featured = rc.Featured, Id = rc.RecordId, PhaseName = rc.PhaseName, rc.ProductionDate, jac.PublishedDate, Source = jac.Source, Title = rc.Title, rc.UpdatedDate, AttachmentCount = ra.Count(), Attachments = ra, IsAttachment = (ra.Count() != null) ? true : false }; 

这将返回记录,相关的附件。现在我需要这个数据映射到一个视图模型..

public class FlaggedItemModel 
{ 
    public int typeid { get; set; } 
    public string typename { get; set; } 
    public int id { get; set; } 
    public string title { get; set; } 
    public string publishdate { get; set; }  
    public bool featured { get; set; } 
    public string productiondate { get; set; } 
    public string phasename { get; set; } 
    public string updateddate { get; set; } 
    public DateTime updateddateforsorting { get; set; } 
    public bool comments { get; set; } 
    public int numofcomments { get; set; } 
    public bool attachment { get; set; } 
    public int numofattachments { get; set; } 
    public IList<AttachmentModel> attachments { get; set; } 
} 

我想这个代码,但没有工作

var recordlist = journalArticleAttachments.Select(x => new FlaggedItemModel() { attachments = x.Attachments.Where(z => z.ContentId == x.Id).Select(jaa => new AttachmentModel() { attachmentid = jaa.AttachmentId, typeid = jaa.ContentType, title = jaa.FileName }).ToList(), numofcomments = x.CommentsCount, comments = x.Comments, featured = x.Featured, id = x.Id, phasename = x.PhaseName, productiondate = (x.ProductionDate.HasValue) ? x.ProductionDate.Value.ToShortDateString() : string.Empty, publishdate = (x.PublishedDate.HasValue) ? x.PublishedDate.Value.ToShortDateString() : string.Empty, title = x.Title, typeid = 1, typename = "Journal Scan", updateddate = x.UpdatedDate.ToShortDateString(), updateddateforsorting = x.UpdatedDate }); 

如何解决这个问题?

+2

在背景中是否有类似于实体框架的东西?我认为你应该尝试使用导航属性来代替加入。 – 2013-05-02 09:05:43

+0

是的,有实体框架的工作。 – dany 2013-05-02 09:42:05

+0

你可以展示班级模特吗?我认为使用导航属性将使这更容易! – 2013-05-02 09:59:05

回答

0

由于您试图让数据库将日期时间转换为不知道该如何操作的格式化的短日期字符串,您会收到此错误。我建议改变你的模型,让生产日期成为日期时间字段,并在你的视图中适当地格式化它。将日期时间更改为控制器(或DAL)中的字符串不是适当的地方。

或者,如果您坚持在您的viewmodel中有shortdate,请将查询初始化为日期时间,然后在查询上调用.ToList(),然后将该结果投影到最终视图中,结果将作为日期时间从数据库中返回,然后您可以将它转换为C#中的shortdate。这样的事情:

var recordlist = journalArticleAttachments.Select(x=>new { ..., publishdate, ...}).ToList().Select(x=>new { ..., publishdate = (publishdate==null) ? publishdate.ToShortDateString() : string.Empty, ...});