3

次の方法でIdフィールドとNameフィールドを取得したテーブルEmployeeがあります。

var users = context.Employees.ToList()
                   .Select(employee => new KeyValuePair<int, string>(employee.Id,employee.Name)); 

その部分は正常に機能します。私の問題は、外部キーが設定されている別のテーブルAttendanceがあり、DateTime値であるLoginDateフィールドがあることです。ユーザーは複数回ログインできるので、過去7日間にユーザーがログインした回数の明確な値を取得したいと思います。

foreach (var user in users)
{
    var days = context.Attendances.Where(x => x.Id == user.Key && x.LoginDate.Date > DateTime.Now.AddDays(-7)).Distinct().ToList();
     int count = days.Count();
     _attendanceTable.Rows.Add(user.Key, user.Value, count);
 }

出席テーブルのクエリを実行しているときに例外が発生します。

指定されたタイプメンバー'Date'は、LINQtoEntitiesではサポートされていません。初期化子、エンティティメンバー、およびエンティティナビゲーションプロパティのみがサポートされます。

4

2 に答える 2

5

すべてを1つのクエリで実行できます。

var date = DateTime.Now.AddDays(-7).Date; // I think you need date only here
var query = from e in context.Employees
            join a in context.Attendances on e.Id equals a.Id into g
            select new
            {
                e.Id,
                e.Name,
                Count = g.Where(x => x.LoginDate > date)
                         .GroupBy(x = > new {
                               x.LoginDate.Year,
                               x.LoginDate.Month,
                               x.LoginDate.Day 
                          }).Count()
            };

foreach(var user in query)
   _attendanceTable.Rows.Add(user.Id, user.Name, user.Count);

またDate、DateTimeのプロパティはEntityFrameworkではサポートされていません。日付部分ごとに出席をグループ化するには、匿名オブジェクトを使用する必要があります。

生成されたSQLクエリは次のようになります。

SELECT [Extent1].[Id] AS [Id], 
       [Extent1].[Name] AS [Name], 
    (SELECT 
        COUNT(1) AS [A1]
        FROM ( SELECT DISTINCT 
            DATEPART (year, [Extent2].[LoginDate]) AS [C1], 
            DATEPART (month, [Extent2].[LoginDate]) AS [C2],
            DATEPART (day, [Extent2].[LoginDate]) AS [C2],
            FROM [dbo].[Attendances] AS [Extent2]
            WHERE [Extent1].[Id] = [Extent2].[Id]
        )  AS [Distinct1]) AS [C1]
FROM [dbo].[Employees] AS [Extent1]
于 2012-12-22T09:06:08.940 に答える
2

コードで実行できる操作の一部は(少なくともクリーンにではなく)SQLに変換されないため、変換を改善するために特定の操作を移動する必要があります。

//Figure out the day you want in advance
var sevenDaysAgo = DateTime.Now.Date.AddDays(-7);
var results = users.Select(user => new {
     user.Key,
     user.Value,
     Count = users.Join(context.Attendances, 
                        user => user.Key,
                        attendance => attendance.EmployeeId,
                        (user, attendance) => attendance.LoginDate)
                  .Where(date => date > sevenDaysAgo)
                  .Select(date => date.Day)
                  .Distinct()
                  .Count()
});

foreach (var result in results)
{        
    _attendanceTable.Rows.Add(result.Key, result.Value, result.Count);
}
于 2012-12-22T08:54:41.690 に答える