Linq查询,方法中混乱的where子句

5

我有一个查询,应该返回当前一周报告的总工时。下面的代码返回正确的总工时,但不是针对数据库中特定的用户。

    public int reportedWeekTime(int currentWeek, string username)
        {
            var totalTime = (from u in context.Users
                         from r in context.Reports
                         from w in context.Weeks
                         from d in context.Days
                         where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id   == w.ReportId && w.DayId == d.Id
                         select d.Hour).DefaultIfEmpty(0).Sum();
            return totalTime;
        }

第一种方法返回数字24,这是正确的,但正如我所说,不适用于特定用户。
我正在尝试做到这一点,但返回值为0。我做错了什么?
    public int reportedWeekTime(int currentWeek, string username)
        {
            var totalTime = (from u in context.Users
                         from r in context.Reports
                         from w in context.Weeks
                         from d in context.Days
                         where u.Id == r.UserId && r.weekNr.Equals(currentWeek) && r.Id == w.ReportId && w.DayId == d.Id && u.Username.Contains(username)
                         select d.Hour).DefaultIfEmpty(0).Sum();
            return totalTime;
        }

也许你应该将用户名设置为类中的属性。我知道 WP7 Linq 对于传递给方法的值并不是很好。 - Preben Huybrechts
请使用join操作符,访问http://code.msdn.microsoft.com/LINQ-Join-Operators-dabef4e9。 - Habib
将用户名像这样传递给方法可以用于我使用的另一个linq查询,但不适用于这个特定的查询。 - rickard
好的,none of context.Users 包含 "username"。你应该尝试显示此查询的结果以了解发生了什么:context.Users.Where(user => !user.Contains(username)) - Kevin Gosse
1
所以你的问题不在于你的linq查询,而在于你没有符合条件的用户名。请注意,Contains方法是区分大小写的。 - Kevin Gosse
显示剩余2条评论
1个回答

2

更新 - 故障排除方法,创建一个带有u.Username属性、字符串用户名和比较的新匿名类。这样更容易理解正在发生的事情。

var users = (from u in context.Users
             select new
             { 
               UsernameDb = u.Username,
               UsernameSearch = username,
               Comparison = u.Username.Contains(username),
             }).ToList();

Translated

我会稍微修改您的查询:

  1. 使用 join 替代带有 where 子句的 from
  2. 移除 DefaultIfEmpty(0)

(1) 更多是为了可读性,但我认为 (2) 是问题的原因。

var totalTime = (from u in context.Users
                 join r in context.Reports on u.Id equals r.UserId
                 join w in context.Weeks on r.Id equals w.ReportId
                 join d in context.Days on w.DayId equals d.Id
                 where r.weekNr.Equals(currentWeek) && u.Username.Contains(username)
                 select d.Hour).Sum();

我会确保以下查询返回结果。如果没有结果,则可能是你的问题。
var users = from u in context.Users
            where u.Username.Contains(username)
            select u;

我很想尝试这个,但是选择语句给了我一个错误代码:“运算符'??'不能应用于类型为'int'和'int'的操作数”。 - rickard
@rickard - 好的,我假设d.Hour是可空的。你尝试过去掉DefaultIfEmpty(0)吗?为什么要加上它? - Aducci
我使用了DefaultIfEmpty,如果一个人添加了报告但没有添加工时,则会返回值0。但问题仍然存在,我知道它应该返回一个值,但它并没有。相反,它给了我“转换为值类型'Int32'失败,因为实例化的值为空。结果类型的泛型参数或查询必须使用可空类型。” - rickard
@rickard - 我现在明白了。u.Username.contains(username) 没有返回任何结果。 - Aducci
1
从无处到现在,解决方案现在正在运行。我将您的答案标记为正确答案。我只是再次添加了DefaultIfEmpty(0),以确保如果没有设置值,该方法将返回0。感谢您的帮助。 - rickard
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接