如何改进此查询并检查linq-expression中的可空对象

时间:2014-01-30 16:31:02

标签: c# linq linq-to-entities

我正在处理的当前项目包括Application,BLL和数据层。目前,该应用程序直接引用了数据层。由于我想正确应用OO,我想通过在BLL层中添加Business对象来打破Application-和datalayer之间的关系。目前非常基本,只有与实体对象相同的属性,但我想稍后使用自己的构造函数en CRUD-methods扩展它们。

这部分工作,下面的查询为我提供了一个项目清单,里面有他们的投资组合项目。但是,组合项可以最多包含三个图像,包含在对象中。我特别说,可以,因为它们可以为NULL。 NULL-able对象目前正在给我这个问题,理想情况下我想在查询中检查里面的图像,但我不知道如何(如果它甚至可能)。

这是查询;

List<BLL.Objects.Portfolio> listOfPortfolios = (from pf in _portfolioService.AsQueryable() //Generic service returning IQueryable
    where !pf.IsDeleted && pf.IsPublished
    orderby pf.PublishStart
    select new BLL.Objects.Portfolio //Object in business layer
   {
       Id = pf.Id,
       IsDeleted = pf.IsDeleted,
       IsPublished = pf.IsPublished,
       LastModified = pf.LastModified,
       Name = pf.Name,
       Projects =
            (from prj in pf.Projects //prj = object in datalayer
             where !prj.IsDeleted && prj.IsPublished
             orderby prj.PublishStart descending
             select new BLL.Objects.Project //Object in business layer
            {
                Id = prj.Id, 
                Title = prj.Title,
                Description = prj.Description, 
                EndDate = prj.EndDate, 
                IsDeleted = prj.IsDeleted, 
                IsPublished = prj.IsPublished, 
                LastModified = prj.LastModified,
                PublishEnd = prj.PublishEnd,
                SmallImage = new Image //This line causes the error. Image is a object in the business layer
                 {
                     Extension = prj.SmallImage.Extension, //prj.smallimage is an entity in my datalayer
                     FileContent = new ImageContent
                       {
                           Id = prj.SmallImage.FileContent.Id, 
                           Content = prj.SmallImage.FileContent.Content
                       }, 
                     Filename = prj.SmallImage.Filename, 
                     Height = prj.SmallImage.Height, 
                     Id = prj.SmallImage.Id, 
                     IsDeleted = prj.SmallImage.IsDeleted, 
                     IsPublished = prj.SmallImage.IsPublished, 
                     LastModified = prj.SmallImage.LastModified, 
                     MimeType = prj.SmallImage.MimeType, 
                     PublishEnd = prj.SmallImage.PublishEnd,
                     PublishStart = prj.SmallImage.PublishStart
                 }
            }).ToList(),

              //MediumImage = new Image { Extension = prj.MediumImage.Extension, FileContent = new ImageContent { Id = prj.MediumImage.FileContent.Id, Content = prj.MediumImage.FileContent.Content }, Filename = prj.MediumImage.Filename, Height = prj.MediumImage.Height, Id = prj.MediumImage.Id, IsDeleted = prj.MediumImage.IsDeleted, IsPublished = prj.MediumImage.IsPublished, LastModified = prj.MediumImage.LastModified, MimeType = prj.MediumImage.MimeType, PublishEnd = prj.MediumImage.PublishEnd }

       //pf.Projects.Where(
       //    p => !p.IsDeleted && p.IsPublished)
       //         .OrderByDescending(p => p.PublishStart)
       //         .ToList(),
       PublishEnd = pf.PublishEnd,
       PublishStart = pf.PublishStart,
       SystemName = pf.SystemName
   }).ToList();

当我向查询添加带有'SmallImage'的行时,我得到的错误如下:

"The cast to value type 'System.Guid' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."

我知道这是因为具有此特定投资组合的项目列表包含4个项目,其中只有一个项目具有SmallImage。我对此有两个问题是:

  1. 如何在linq查询中检查对象为空以防止出现此问题?
  2. 这个非常大的查询可以简化吗?

1 个答案:

答案 0 :(得分:1)

只需添加一个空检查:

            SmallImage =  prj.SmallImage == null 
                        ? null 
                        : new Image 
             {
                 Extension = prj.SmallImage.Extension, //prj.smallimage is an entity in my datalayer
                 FileContent = new ImageContent
                   {
                       Id = prj.SmallImage.FileContent.Id, 
                       Content = prj.SmallImage.FileContent.Content
                   }, 
                 Filename = prj.SmallImage.Filename, 
                 Height = prj.SmallImage.Height, 
                 Id = prj.SmallImage.Id, 
                 IsDeleted = prj.SmallImage.IsDeleted, 
                 IsPublished = prj.SmallImage.IsPublished, 
                 LastModified = prj.SmallImage.LastModified, 
                 MimeType = prj.SmallImage.MimeType, 
                 PublishEnd = prj.SmallImage.PublishEnd,
                 PublishStart = prj.SmallImage.PublishStart
             }