2013-11-24 106 views
0

我大力搜索对此的答案,但我无法找到(或理解)解决方案。我有一个查询,我正在加入另一个可能有或没有关联记录的表。下面是该查询:实体框架 - 处理没有来自连接表的记录的连接

var educationUniversity = result.new_educationUniversity.Select(c => new 
    { c.majorDegree, c.dateEnd, c.dateStart, c.institutionName, 
     c.degreeProgramCompletionStatus, c.institutionAddress, 
     attachmentId = c.attachmentId ?? 0, 
     fileName = c.new_attachments.fileName ?? "No Attachment"}).ToList(); 

第一个表是“new_educationUniversity”,它拥有用户的学院或大学学位的细节。用户可能已上传附件(存储在“new_attachments”表中)。 attchmentID是“new_attachments”表中的主键和“new_educationUniversity”表中的外键。 EF看到了这种关系。

我将结果绑定到中继器,但如果没有相关的附件,代码将失败。一切工作正常,如果有附件或如果我删除对fileName的引用。

上面,我正在处理,如果fileName为NULL(或至少我试图),但我怀疑我的问题是该记录根本不存在,这是不同于NULL我猜。我试过使用类似:c.new_attachments.fileName.SingleOrDefault()或DefaultIfEmpty()没有运气。

作为比喻,假设您有一个CUSTOMERS表和一个ORDERS表。你想查询以下:

- 客户姓氏 - 客户第一名称 - 客户最近的订单ID

从来没有谁买什么东西。然而,您已注册的客户。我确信我正在做一些完全不讨好的事情,所以任何协助都非常感谢。谢谢!

+1

你要求的是一个“左连接”,有很多例子可以说明如何做到这一点。 http://stackoverflow.com/questions/3404975/left-outer-join-in-linq或http://msdn.microsoft.com/en-us/library/vstudio/bb397895.aspx –

+0

找到一种技术,通过工作这个链接虽然我不完全理解。谢谢! – Matt

回答

0

所以,你有几件事会在这里:

  • 你可以在你的参考c.new_attachments.fileName一个空引用异常。如果new_attachments为null,那么这将引发异常。包括空合并运算符(??)将无济于事,因为您试图访问可能为空的某个属性。
  • 除非你懒惰加载(通常是坏的),否则你没有理由试图创建一个动态类型的对象发送到你的中继器。只需直接传递result.new_educationUniversity对象即可。

什么是解决方案? 我会创建一个部分类,为new_educationUniversity类添加一个新属性。添加一个null-reference-safe属性引用来确定new_educationUniversity的new_attachments属性的文件名。然后,将转发器绑定到您的新媒体资源。例如:

public partial class new_educationUniversity { 
    public String AttachmentFileName { 
     get { 
      if (new_attachments == null) 
       return ""; 
      else 
       return new_attachments.fileName; 
     } 
    } 
} 
+0

我不相信我正在使用延迟加载。当通过名称遍历表层次结构时,我忘记了在EF中调用它。如果EF知道我的CUSTOMERS表,并且我的ORDERS表已加入CUSTOMER_ID列,那么在我收到订单后,请在订单 var order = orders.Where(c => c.id == 3).Single(); 我仍然可以获得客户的名字,order.customer.firstName 这样做不好吗?我的SQL技能和我的需求是非常基本的。谢谢! – Matt

+0

如果您正在检索order.customer(获取order.customer.firstName),那么它会延迟加载。在运行查询来检索您的订单之后。如果您在初始查询中使用.Include(),并且急于加载关联的客户对象,那么您正在加载。假设你在某个时候确实需要这些客户,那么急切的加载会更好。 –

0

以下代码行似乎正在工作。

var educationUniversity = result.new_educationUniversity.Select 
(c => new { c.majorDegree, c.dateEnd, c.dateStart, c.institutionName, 
c.degreeProgramCompletionStatus, c.institutionAddress, attachmentId = c.attachmentId ?? 0, 
fileName = (c.new_attachments == null ? "***NO ATTACHMENT***" : c.new_attachments.fileName)}).ToList(); 

我不完全了解这行的意思:

fileName = (c.new_attachments == null ? "***NO ATTACHMENT***" : c.new_attachments.fileName)} 

我认为它说:“如果无所不有与字符串替换‘没有附件’,否则用的是在DB”

这是可以接受的吗?到现在为止还挺好。谢谢!