【问题标题】:Linq to SQL Design questionLinq to SQL 设计问题
【发布时间】:2010-12-01 04:05:46
【问题描述】:

我经常需要组合来自多个表的数据并将结果显示在 GridView 控件中。

我可以在 Page_load 事件中内联编写一个 Linq 查询,返回一个组合了我需要的所有字段的匿名类型,并将结果数据绑定到 GridView 控件。

  • 问题:我使用Scott Guthrie on his blog 所述的“辅助方法”。这样的辅助方法不能返回匿名类型。对于这种方法,查询必须是内联的。

我可以编写一个返回我需要的数据的数据库视图,并编写一个辅助方法来查询它返回的这个(新的和已知的)类型。

  • 问题:我的数据库架构中需要很多视图,并且我会引入很多冗余方面的数据。我也失去了使用 Linq 的一些优势 - 从数据库中删除所有业务逻辑。

我想采用一种方法,让我将 Linq 查询保留在辅助方法中,同时允许我在各自的数据绑定表达式中访问网格上我需要的所有属性。这个可以吗?

【问题讨论】:

  • 这是 C# 吗?如果是,您将通过添加 C# 标记获得更多视图。如果您使用的是 GridView 控件,我假设是 ASP.NET。
  • 我认为语言并不重要。

标签: asp.net linq-to-sql controls data-binding


【解决方案1】:

我不知道是否有一种可行的方法来使用匿名类型来实现这一点。但是我有一个可以在 WinForms 中使用的建议,但我不确定 ASP.NET。

您需要的是一种具有属性的类型,其中在编译时既不知道属性的数量,也不知道属性的类型和名称。创建这种东西的一种方法是ICustomTypeDescriptor

您必须创建一个实现此接口的类型,该类型具有一个私有的对象后备存储,该对象支持由查询返回的属性,用于查询中的一行。然后您实现GetProperties() 以每列返回一个PropertyDescriptor,并实现PropertyDescriptor.GetValue()PropertyDescriptor.SetValue() 以访问支持数组。

通过实现PropertyDescriptor.Name,您将获得正确的列名;这可能需要另一个存储属性名称的后备存储。还有更多需要实现,但最终您的新类型将表现得几乎像普通类型 - 现在是 if - 如果您绑定到的控件知道并使用 ICustomTypeDescriptor

更新

我刚刚发现一段文字说明 ASP.NET 数据绑定知道并使用ICustomTypeDescriptor

【讨论】:

  • @Daniel 有趣的建议 - 事实证明解决方案要简单得多,请参阅我自己的答案。
【解决方案2】:

我经常问错问题。促使我研究匿名类型的原因是 GridView 的一个明显限制——我无法在 <asp:BoundField> 中使用数据绑定表达式(DataField 参数只接受 Linq 查询引入的表的列名)。

事实证明,在 TemplateField 中 可以使用 Eval 和访问 Linq 数据项的成员,而 Linq 会为我处理查询。 换句话说,我可以将查询保留在我的辅助方法中,让它返回一个主数据库表类型(例如 Account),并将 Accounts 绑定到 GridView。 在数据绑定表达式中,我可以访问驻留在其他表中的 Account 对象的数据成员,而无需在查询中显式地拉入它们。完美。

【讨论】:

    【解决方案3】:

    Scott 在该系列的早期文章中谈到了在插入网格之前对结果集进行整形:

    Part 3 - Querying our Database

    向下滚动到“塑造我们的查询结果”。

    【讨论】:

    • 我也读过这部分,这正是我困惑的地方——在这部分中,他使用内联查询将匿名类型绑定到网格,这对于内联查询非常有效,但方法当您按照他在第 9 部分中的建议扩展 DataContext 时会崩溃。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多