4

我需要一些帮助来使用 lambda 表达式来删除我的 Entity Framework 上下文中的重复条目。我有一个包含以下列的表格:

Id, DateOfIncident, Description, EmployeeId, IncidentTypeId, and IsAttendanceIncident

我想删除DateOfIncident, EmployeeID, IncidentTypeID and IsAttendanceIncident are the same. 我确实想保留一个条目的重复条目。我知道如何在 SQL 中使用带有 CTE 的存储过程来执行此操作,但我无法弄清楚如何使用 Lambda 表达式来完成此任务。

此代码返回一个列表,不包括我的重复项,但现在我该如何删除那些不在此列表中的重复项?

  var query = db.Incidents.Where(x => x.IsAttendanceIncident == "Y").GroupBy(x => new { x.EmployeeId, x.DateOfIncident, x.IsAttendanceIncident })
         .Select(x => x.FirstOrDefault());

更新:

所以我继续编写了自定义的 IEqualityComparer。现在如何使用 id 删除我的上下文中不在我 distinctItems 中的事件?

 static void Main(string[] args)
    {
        DALIncidents.AttendanceEntities1 db = new DALIncidents.AttendanceEntities1();

       IEnumerable<DALIncidents.Incident> distinctItems = db.Incidents.Where(c => c.IsAttendanceIncident == "Y");
       distinctItems = distinctItems.Distinct(new DALIncidents.DistinctIncidentComparer());

       Console.ReadLine(); 
    }
4

4 回答 4

9
var query = db.Incidents
    .Where(x => x.IsAttendanceIncident == "Y")
    .GroupBy(x => new { x.EmployeeId, x.DateOfIncident, x.IsAttendanceIncident })

示例 1:

    .Select(x => x.FirstOrDefault());  // your original code which retrieves entities to not delete

var dupes = db.Incidents.Except( query ); // get entities to delete

示例 2:

    .SelectMany( x => x.OrderBy( y => y.Id ).Skip(1) ); // gets dupes directly

var dupes = query; // already have what we need

最后:

foreach( var dupe in dupes )
{
    db.Incidents.Remove( dupe );
}

从我之前使用的测试上下文生成的示例 SQL,其中 Person 实体与手表具有 1:N 关系:

C#:

context.Persons.SelectMany(x => x.Watches.OrderBy(y => y.Id).Skip(1))

生成的 SQL:

SELECT 
1 AS [C1], 
[Skip1].[Id] AS [Id], 
[Skip1].[Brand] AS [Brand], 
[Skip1].[Person_Id] AS [Person_Id]
FROM  [dbo].[Persons] AS [Extent1]
CROSS APPLY  (SELECT [Project1].[Id] AS [Id], [Project1].[Brand] AS [Brand], [Project1].[Person_Id] AS [Person_Id]
    FROM ( SELECT [Project1].[Id] AS [Id], [Project1].[Brand] AS [Brand], [Project1].[Person_Id] AS [Person_Id], row_number() OVER (ORDER BY [Project1].[Id] ASC) AS [row_number]
        FROM ( SELECT 
            [Extent2].[Id] AS [Id], 
            [Extent2].[Brand] AS [Brand], 
            [Extent2].[Person_Id] AS [Person_Id]
            FROM [dbo].[Watches] AS [Extent2]
            WHERE [Extent1].[Id] = [Extent2].[Person_Id]
        )  AS [Project1]
    )  AS [Project1]
    WHERE [Project1].[row_number] > 1 ) AS [Skip1]
于 2013-08-12T12:40:43.163 回答
1
var query = db.Incidents.Where(x => x.IsAttendanceIncident == "Y")
                .GroupBy(x => new { x.Id, x.EmployeeId, x.DateOfIncident, x.IsAttendanceIncident })
                .Select(x => x.FirstOrDefault());


var query2 = from duplicate in db.Incidents
                 .Where(x => x.IsAttendanceIncident == "Y" && !query.Any(i => i.Id == duplicate.Id));

query2 现在将只包含重复项?

于 2013-08-12T12:31:20.470 回答
0
var query = db.Incidents.Where(x => x.IsAttendanceIncident == "Y").GroupBy(x => new { x.EmployeeId, x.DateOfIncident, x.IsAttendanceIncident })
     .SelectMany(x => x.Skip(1));
于 2013-08-12T12:32:55.943 回答
0

您将需要使用 Distinct 功能,如果您只想使用某些字段,则需要创建一个平等比较器。(IEqualityComparer)

啊刚刚看到上面的评论,查看更多:

使用 linq 删除列表中的重复项

于 2013-08-12T12:30:13.713 回答