【问题标题】:Entity Framework - Handling a join with no records from join table实体框架 - 处理连接表中没有记录的连接
【发布时间】:2013-11-24 19:27:48
【问题描述】:

我努力寻找这个问题的答案,但我无法找到(或理解)解决方案。我有一个查询,我正在加入另一个可能有也可能没有关联记录的表。这是查询:

  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 看到了这种关系。

我将结果绑定到转发器,但如果没有相关附件,则代码在上面的行中失败。如果有附件或者我删除了对文件名的引用,一切正常。

上面,我正在处理文件名是否为 NULL(或者至少我正在尝试),但我怀疑我的问题是该记录根本不存在,这与我猜的 NULL 不同。我试过使用类似的东西: c.new_attachments.fileName.SingleOrDefault() 或 DefaultIfEmpty() 没有运气。

打个比方,假设您有一个 CUSTOMERS 表和一个 ORDERS 表。您要查询以下内容:

-客户姓氏 -客户名字 - 客户最近的订单 ID

但是,您的注册客户从未购买过任何东西。我确定我正在做一些完全不合时宜的事情,因此非常感谢任何帮助。谢谢!

【问题讨论】:

标签: c# sql entity-framework join


【解决方案1】:

所以你有一些事情发生在这里:

  • 您可以在对 c.new_attachments.fileName 的引用中获得空引用异常。如果 new_attachments 为空,那么这将引发异常。包含 null 合并运算符(??)将无济于事,因为您正在尝试访问可以为 null 的东西的属性。
  • 除非您是延迟加载(通常很糟糕),否则您没有理由尝试创建一个动态类型的对象来发送到您的转发器。直接传递 result.new_educationUniversity 对象即可。

解决办法是什么? 我会创建一个部分类来为你的 new_educationUniversity 类添加一个新属性。添加空引用安全属性引用以确定 new_educationUniversity 的 new_attachments 属性的文件名。然后,将转发器绑定到您的新属性。比如:

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

【讨论】:

  • 我不相信我在使用延迟加载。当您通过名称遍历表层次结构时,我忘记了它在 EF 中的名称。如果 EF 知道我的 CUSTOMERS 表和我的 ORDERS 表在 CUSTOMER_ID 列上连接,那么在我得到一个订单 var order = orders.Where(c => c.id == 3).Single();我仍然可以使用 order.customer.firstName 获取客户的名字这样做不好吗?我的 SQL 技能和我的需求非常基本。谢谢!
  • 如果您在运行查询以检索订单后检索 order.customer(以获取 order.customer.firstName),则为延迟加载。如果您在初始查询中使用 .Include() 并急切加载关联的客户对象,那么您就是急切加载。假设您在某个时候确实需要客户,那么急切加载会更好。
【解决方案2】:

以下代码行似乎可以正常工作。

 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)}

我假设它说“如果没有任何内容,请用字符串“NO ATTACHMENT”替换,否则使用数据库中的内容”

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

【讨论】:

    猜你喜欢
    • 2016-07-28
    • 1970-01-01
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    相关资源
    最近更新 更多