【问题标题】:Flattening an Entity Framework objectquery result with includes使用包含展平实体框架对象查询结果
【发布时间】:2012-01-05 04:32:39
【问题描述】:

我正在尝试掌握 Entity Framework,但有一件事让我很头疼。我仍然不完全确定术语并没有帮助,而且我试图避免同时学习 LINQ,所以谷歌搜索很困难。

我有两张表,公司和地址是一对多的关系。如果我写以下内容:

ObjectQuery<Company> companies = queryContext.Companies.Include("Addresses");

看起来我得到了我想要的(公司 -> 结果视图 [0].Addresses.Count 是 > 0)

我现在想做的是将公司名称和所有地址绑定到 ASP.NET 应用程序中的网格视图

this.CompaniesGrid.DataSource = companies;
this.CompaniesGrid.DataBind();

<asp:GridView runat="server" ID="CompaniesGrid" AllowSorting="true">
    <Columns>
        <asp:BoundField DataField="Name" />
        <asp:BoundField DataField="Address" />
    </Columns>
</asp:GridView>

这本身会引发错误 (A field or property with the name 'Address' was not found on the selected data source) - 我认为是因为公司 -> Results View[0].Name 存在,但 .Address 不存在(因为它隐藏在 Addresses 关系中)。绑定到 Addresses.Address 也无济于事。

我在this thread 的底部发现了一个非常丑陋的解决方法,但如果可能的话我宁愿避免它。

有什么方法可以“展平”我的结果,以便顶级对象为所有包含的字段提供地址?

非常感谢任何帮助!

【问题讨论】:

  • 你应该看看 AutoMapper。

标签: asp.net entity-framework objectquery


【解决方案1】:

您的 objectquery 正在返回一个图表。虽然我认为如果你想在 .NET 中编程,你真的应该把它吸起来并学习 linq(大笑……除了真的,你应该),你可以编写一个投影查询来带回扁平的结果并在 ASP 中绑定这些结果。网。

扁平化的诀窍是从关系中的“孩子”开始。所以像这样:

grid.datasource= context.Addresses.Select
          (a=>new {a.Company.CompanyName,a.Street, a.City}).ToList();

(代码无法保证,因为 stackoverflow UI 不提供 .net 智能感知或编译时检查。嘘。)。

【讨论】:

  • 感谢您的建议。最后,我采用了 linq 和你的 child-up 方法的混合方法:IQueryable query = from adds in context.Addresses select new { adds.Company.Name, adds.Address1, adds.City };
  • 太棒了。 LINQ 真的很棒。值得努力学习。 FWIW,我的代码 LINQ。不同之处在于最后我使用 LINQ 方法 ToList 来执行查询并返回结果。我通常会进一步分开,以便 UI 代码甚至不知道 EF。但我将网格绑定到结果列表,而不是直接绑定到查询。
  • aha 我还在学习 - 我收到了 ToList() 调用,但是当我开始查看 LINQ 时,我只看到查询语法,而不是使用 Select() 等函数的替代方法语法
  • 扁平化的诀窍是从关系中的“孩子”开始。 - 那条评论可以救命!我是 EF 的新手,我一直在绞尽脑汁想把层次结构弄平。现在它像白天一样清晰。谢谢!
【解决方案2】:

我不完全明白为什么你觉得使用模板字段的解决方案很难看?

绑定字段只能绑定到常规属性。要绑定到导航属性,您必须使用模板字段。

所以你提到的线程中的代码解决了你的问题。

如果你真的觉得这很难看,你可以实现自己的绑定字段并使其支持嵌套绑定,但我认为使用模板字段是一个更好的解决方案。

【讨论】:

  • 我想我认为它丑陋,因为我认为必须有更好的方法来做到这一点——这难道不是我们想要抽象数据的部分原因吗?如果一家公司有 1 个或多个地址,我不在乎数据库是否将其存储在单独的表中。也许我需要创建一个连接两个表的新实体?
  • 创建一个单独的 DTO 是可能的,但是在将实体转换为 DTO 时,您就有了耦合。您还可以使用 LINQ 查询来初始化您的 Gridview,该查询将转换为具有展平数据的匿名类型。
  • 最终我接受了你的第二个建议(linq 扁平化数据)。在这上面花了更多时间并找到了一个可行的解决方案后,我更加确信 eval 解决方法很丑,因为它没有提供编译时检查,而且根据我的经验,在 aspx 中的 asp 标签之间写的任何东西都很难使用
猜你喜欢
  • 2011-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 2010-12-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多