我有一个包含以下字段的MS SQL表。我正在使用实体框架:
EntryId
EntryType
Operation
UpdatedTime_UTC
EntryId和EntryType字段可以包含重复值。创建对象时,会添加一条记录,并将其“操作”字段设置为“已添加”。如果对象被修改,则使用与第一个记录相同的EntryId和EntryType值写入另一个记录,但“operation”字段将被设置为“modified”。当对象被删除时(你已经猜到了),另一条记录的前面记录与EntryId和EntryType值相同,但“operation”字段将被设置为“已删除”。
一些示例数据如下所示:
ID1, Type1, “added”, 2012-08-20 09:15:50
ID2, Type1, “added”, 2012-08-21 09:15:50
ID1, Type1, “modified”, 2012-08-22 09:15:50
ID1, Type1, “modified”, 2012-08-23 09:15:50
ID2, Type1, “deleted”, 2012-08-24 09:15:50
显示有关两个对象(ID1和ID2)的信息。两者都被添加到表中,但ID1被修改,ID2被删除。作为协调过程的一部分,我需要检查一个对象是否已被删除,我的表中必须有一条记录,其中匹配的EntryId的操作设置为“已删除”。如果没有我的代码将添加一个。
现在我的问题。当我的系统认为给定的“EntryType”没有对象时,我有一个函数被调用。我需要确认我的表中“EntryType”的所有记录都有一个“操作”设置为“已删除”的记录。在上面显示的数据中,“ID1”没有“已删除”条目。如果对象仍然存在则这很好但如果对象已经消失则很糟糕。我正在使用以下Linq获取一个分组列表,我在其中传递了我感兴趣的“entityType”。
var item = _ctx.JournalSet
.Where(x => x.EntryType == entityType)
.OrderBy(x => x.UpdatedTime_UTC)
.GroupBy(x => x.EntryId);
然后,我使用此代码查看每个组,看它是否有“已删除”条目。如果不是,我在表格中添加新记录。
foreach (var item in result)
{
if (item.Last().Operation != "deleted")
{
// no 'deleted' entry found. time to add a new entry.
}
}
我想要做的是修改我的Linq语句,以便只在需要添加删除的条目时才返回EntryId和EntryType详细信息。
附加信息:删除的记录的日期时间总是晚于“添加”或“修改”记录,因此在按“UpdatedTime_UTC”排序时,最后一个条目应为“已删除”,如果它存在于给定的entryId
是否有可能创建一个Linq语句来完成上述操作而不需要foreach的东西?
答案 0 :(得分:2)
你尝试过这样的事吗?
var item = _ctx.JournalSet
.Where(x => x.EntryType == entityType)
.OrderBy(x => x.UpdatedTime_UTC)
.GroupBy(x => x.EntryId)
.Where(y => y.Last().Operation != "deleted");
答案 1 :(得分:0)
我会找到您缺少已删除条目的记录,然后根据需要添加它们:
var itemsToAdd = _ctx.JournalSet
.Where(x => x.EntryType == entityType)
.OrderBy(x => x.UpdatedTime_UTC)
.GroupBy(x => x.EntryId)
.Where(grp => grp.Last().Operation != "deleted");
然后您可以使用foreach
添加项目,甚至可以通过第二个LINQ Select
语句(映射到新类型)执行此操作,具体取决于您要添加的集合。第二个陈述可能类似于:
collection.AddRange(itemsToAdd.Select(grp => new YourType(grp.Key.EntryId, "deleted")));
(这是假设一个构造函数,它采用ID +“删除”,根据需要进行编辑......)