【问题标题】:Binding Linq Query with Aggregates to ListView WPF C#将带有聚合的 Linq 查询绑定到 ListView WPF C#
【发布时间】:2019-07-22 17:51:18
【问题描述】:

我有一个“TimePunch”类,它记录每个用户的输入/输出时间配对以及一个标志级别,它继承自 INotify 并具有许多蓬松的公共获取/返回,为简单起见将省略。

{
    private int ID;
    private string UserID = App.Username;
    private DateTime TimeIn;
    private DateTime TimeOut;
    private int Flag = 0; //0 = None, 1 = Manual, 2 = Edited, 3 = Unlikely, -1 = Deleted
    private string Notes;
...

我将这些集合作为我的列表视图的基础源绑定,并有许多按钮,它们的作用类似于选项卡,以允许经理切换他们正在查看的一周中的哪一天,并且有一个用于更改周末的控件每个用户的日期和过滤。好的,一切都很好。

我想要做的是将第二个 listView 绑定到一个查询,该查询通过汇总每位员工每天的工作时间来显示一种数据源的“概述”。 (TimePunch 的 myHoursView 返回 TimeIn/TimeOut 之间的小数小时)

在 SQL 中,我正在寻找的伪代码类似于:

SELECT UserID, 
MAX(FlagView) As Flag, --'FlagView' ignores -1 or deleted records
SUM(CASE WHEN myTimeIn.DayofWeek = DayofWeek.Monday
    THEN myHoursView Else 0 END) As Monday, 
SUM(CASE WHEN myTimeIn.DayofWeek = DayofWeek.Tuesday  
    THEN myHoursView Else 0 END) As Tuesday,
...
SUM(myHoursView) As Total  
FROM PunchList  
WHERE TimeIn > WeekEnding.AddDays(-7) AND
   <= WeekEnding 
GROUP BY UserID

有没有办法在 LINQ 中干净地做到这一点?

(实体框架是不可能的——主要是为了兼容性)

【问题讨论】:

  • EF 已经出局,但您是说没有数据库交互,还是不使用 EF?在您提到的实例中,是否所有数据都在本地可用并且只需要总结?
  • 我正在使用 Azure SQL 部署,它不能很好地与实体框架配合使用。相反,我编写了一个自定义类来处理所有连接和交换。相关的数据库记录被下载并作为对象集合在本地缓存,理论上我应该能够以与使用 SQL 的源记录类似的方式使用 LINQ 进行操作......我的主要问题是语法,如到目前为止我所做的尝试只是输出列表列表,然后需要额外的 C# 编码和合并才能获得所需的输出......

标签: c# sql wpf linq xaml


【解决方案1】:

此建议是改用 ADO.Net 并调用已设置为从 Azure/SQL Server 返回 JSON 的存储过程。然后将从 sproc 返回的 JSON 反序列化为结构/实例,然后绑定到正确的列表视图。

  1. 在 Azure DB 中创建一个存储过程,并在选择结束时通过 For JSON Auto 返回正确的 DTO/Model。
  2. 运行 sproc 并提取 JSON 数据的示例。
  3. 转到 JSON2CSharp 并粘贴 JSON 以创建 DTO 对象。
  4. 将课程放入您的项目中。
  5. 在您的项目中调用 sproc。可以在此 .Net 核心 Nuget 页面 (SQLJSONReader) 上找到一个示例。页面
  6. 可以找到该项目的读者SQLExtensions.cs,并且可以毫无问题地将其复制到您的.Net 代码中。 我编写了 Nuget 包/代码,但尚未创建 .Net 版本)。
  7. 请注意,您可以使用 Microsoft 的 XmlReader,但它会拒绝 JSON 转义,并且无法处理 2033 个字符的数据返回。
  8. 该示例返回一个string,它将是原始 JSON。这需要反序列化到您的列表中。

完成后,您可以调用您的存储过程,获取正确的数据并绑定该数据。

【讨论】:

    【解决方案2】:

    我想你想要这样的东西:

    var result = yourlist.GroupBy(
                     item => item.UserId,
                     item => item.UserId,
                     (key, items) => new { UserId = key,
                                           flag = items.Any(x => x.flag),
                                           monday = items.Where(x => x.DayOfWeek == monday).Sum(x => x.myHoursView), 
     // etc.
    

    【讨论】:

    • 花了一些时间来敲定这一切,但这很有效,有助于我理解 LINQ 的语法。授予 item.UserID 在那里两次。谢谢!! :)
    • @BlackHatCS yw -- 很高兴它有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-13
    • 1970-01-01
    相关资源
    最近更新 更多