Linq Include 语句 returns 一个 iCollection,我无法将其绑定到 Gridview 列
Linq Include statement returns an iCollection, which I cannot bind to Gridview Column
起初我使用连接语句来获取可以绑定到我的 Telerik Gridview 的唯一项目:-
var result = ctx.Offenders
.Join(ctx.Fees, o => o.OffenderId, f => f.OffenderId,
(o, f) => new { Offenders = o, Fees = f })
.Join(ctx.ViolationOffenders, o => o.Offenders.OffenderId, vo => vo.OffenderId,
(o, vo) => new { Offenders = o, ViolationOffenders = vo })
.Join(ctx.Violations, v => v.ViolationOffenders.ViolationId, vo => vo.ViolationId,
(v, vo) => new { Violations = v, ViolationOffenders = vo }).ToList();
这很有效。但是我想更多地了解 linq 和 include 语句。所以我开发了一个新查询:-
var result = ctx.Offenders
.Include(o => o.Fees)
.Include(o => o.ViolationOffenders)
.Include(o => o.ViolationOffenders.Select(of => of.Violation))
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.ToList();
gvwData.DataSource = result;
我很高兴我的 linq 语句变得如此紧凑。但是我在将结果绑定到我的 Telerik Gridview 时遇到问题。
telerik 网格有列:-
<Columns>
<telerik:GridNumericColumn DataField = "YouthNumber" HeaderText="Offender ID" HeaderStyle-Width="100px" FilterControlWidth="50px" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn SortExpression ="LastName" DataField="LastName" HeaderText="LastName" ColumnGroupName="GeneralInfo">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="FirstName" HeaderText="FirstName" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="DateOfBirth" HeaderText="DOB" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="PoliceReportDate" HeaderText="Report Date" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="Amount" HeaderText="Payment Owed" ColumnGroupName="BillingInfo"/>
</Columns>
前 4 列是我的变量结果中的第一级数据项,它们毫无问题地绑定到我的网格。然而,PoliceReportDate 和 Amount 作为 iCollection 返回....也就是它们基本上是一个数组 [] 而不是我之前的 Linq 语句返回的每个单独的 gridRow 的唯一值。
我想弄清楚如何仍然可以使用我的第二个 linq 语句并能够绑定到我的网格。我正在尝试使用 linq 和 entity framework.
学习所有可能性
问题是这两个查询不等价。您在第一个查询预测中使用的名称具有误导性 - Offenders、Violations、Fees(我不明白为什么这是顺便说一句,它没有在任何地方使用)应该真正称为 Offender 和 Violation,因为它们代表单个记录,但是最重要的是第一个查询中的所有连接都是 Group Joins。
为了产生相同的结果,您不需要 .Include
次调用,而是这样的事情
var result = ctx.Offenders.AsNoTracking()
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.SelectMany(o => o.ViolationOffenders, (o, vo) => new { o, vo, vo.Violation }
.ToList();
假设当此代码为 运行 时您在 DataContext 中,Include 语句实际上没有任何效果。它们的主要目的是完全加载可能会在 DataContext 边界之外传递的模型。
Ivan Stoev 的回答非常接近,只是不包括费用,但思路是一样的。您将需要展平数据,使其等同于您的原始查询,该查询正在获取特定违规者的每笔费用和每次违规的记录。你说费用应该针对具体的违规行为,如果是这样的话,那么我必须假设你的数据库结构已经包含了从违规行为到费用的外键引用。
var result = ctx.Offenders
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.SelectMany(o => o.ViolationOffenders, (o, vo) => new { o, vo, vo.Violation })
.SelectMany(v => v.Violation.Fees, (v, vf) => new { v, vf })
.ToList()
起初我使用连接语句来获取可以绑定到我的 Telerik Gridview 的唯一项目:-
var result = ctx.Offenders
.Join(ctx.Fees, o => o.OffenderId, f => f.OffenderId,
(o, f) => new { Offenders = o, Fees = f })
.Join(ctx.ViolationOffenders, o => o.Offenders.OffenderId, vo => vo.OffenderId,
(o, vo) => new { Offenders = o, ViolationOffenders = vo })
.Join(ctx.Violations, v => v.ViolationOffenders.ViolationId, vo => vo.ViolationId,
(v, vo) => new { Violations = v, ViolationOffenders = vo }).ToList();
这很有效。但是我想更多地了解 linq 和 include 语句。所以我开发了一个新查询:-
var result = ctx.Offenders
.Include(o => o.Fees)
.Include(o => o.ViolationOffenders)
.Include(o => o.ViolationOffenders.Select(of => of.Violation))
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.ToList();
gvwData.DataSource = result;
我很高兴我的 linq 语句变得如此紧凑。但是我在将结果绑定到我的 Telerik Gridview 时遇到问题。
telerik 网格有列:-
<Columns>
<telerik:GridNumericColumn DataField = "YouthNumber" HeaderText="Offender ID" HeaderStyle-Width="100px" FilterControlWidth="50px" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn SortExpression ="LastName" DataField="LastName" HeaderText="LastName" ColumnGroupName="GeneralInfo">
</telerik:GridBoundColumn>
<telerik:GridBoundColumn DataField="FirstName" HeaderText="FirstName" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="DateOfBirth" HeaderText="DOB" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="PoliceReportDate" HeaderText="Report Date" ColumnGroupName="GeneralInfo"/>
<telerik:GridBoundColumn DataField="Amount" HeaderText="Payment Owed" ColumnGroupName="BillingInfo"/>
</Columns>
前 4 列是我的变量结果中的第一级数据项,它们毫无问题地绑定到我的网格。然而,PoliceReportDate 和 Amount 作为 iCollection 返回....也就是它们基本上是一个数组 [] 而不是我之前的 Linq 语句返回的每个单独的 gridRow 的唯一值。
我想弄清楚如何仍然可以使用我的第二个 linq 语句并能够绑定到我的网格。我正在尝试使用 linq 和 entity framework.
学习所有可能性问题是这两个查询不等价。您在第一个查询预测中使用的名称具有误导性 - Offenders、Violations、Fees(我不明白为什么这是顺便说一句,它没有在任何地方使用)应该真正称为 Offender 和 Violation,因为它们代表单个记录,但是最重要的是第一个查询中的所有连接都是 Group Joins。
为了产生相同的结果,您不需要 .Include
次调用,而是这样的事情
var result = ctx.Offenders.AsNoTracking()
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.SelectMany(o => o.ViolationOffenders, (o, vo) => new { o, vo, vo.Violation }
.ToList();
假设当此代码为 运行 时您在 DataContext 中,Include 语句实际上没有任何效果。它们的主要目的是完全加载可能会在 DataContext 边界之外传递的模型。
Ivan Stoev 的回答非常接近,只是不包括费用,但思路是一样的。您将需要展平数据,使其等同于您的原始查询,该查询正在获取特定违规者的每笔费用和每次违规的记录。你说费用应该针对具体的违规行为,如果是这样的话,那么我必须假设你的数据库结构已经包含了从违规行为到费用的外键引用。
var result = ctx.Offenders
.Where(o => o.YouthNumber != "" && o.FirstName != "" && o.Fees.Any(f => f.Amount != null))
.SelectMany(o => o.ViolationOffenders, (o, vo) => new { o, vo, vo.Violation })
.SelectMany(v => v.Violation.Fees, (v, vf) => new { v, vf })
.ToList()