我有几个实现 ISortable 接口的类:
public interface ISortable
{
int Id { get; set; }
int? Idx { get; set; }
}
在我的 DbContext 类中,我有一个更新方法,它应该为实现 ISortable 的实体做一些额外的事情:
public void UpdateSingle<T>(T item) where T : class
{
// If entity is Sortable, update the indexes of the records between the new and the old index of the updated entity
var sortable = item as ISortable;
if (sortable != null)
{
Detach(item); // need to detach the entity from the context in order to retrieve the old values from DB
var oldItem = Find<T>(sortable.Id) as ISortable;
if (oldItem != null && sortable.Idx != oldItem.Idx)
{
var entities = FindAll<T>().ToList().Cast<ISortable>();
var oldIdx = oldItem.Idx;
var newIdx = sortable.Idx;
if (newIdx > oldIdx)
{
var toUpdate = entities.Where(a => a.Idx <= newIdx && a.Idx > oldIdx).Select(a => a);
foreach (var toUpdateEntity in toUpdate)
{
toUpdateEntity.Idx = toUpdateEntity.Idx - 1;
}
}
else
{
var toUpdate = entities.Where(a => a.Idx >= newIdx && a.Idx < oldIdx).Select(a => a);
foreach (var toUpdateEntity in toUpdate)
{
toUpdateEntity.Idx = toUpdateEntity.Idx + 1;
}
}
}
Detach(oldItem);
Attach(item); // re-attach to enable saving
}
Entry(item).State = EntityState.Modified;
Commit();
}
我想知道的是这一行:
var entities = FindAll<T>().ToList().Cast<ISortable>();
我必须将 LINQ to SQL 表达式转换为列表,以便将实体转换为 ISortable。我需要将其转换为 ISortable 才能执行此操作:
var toUpdate = entities.Where(a => a.Idx <= newIdx && a.Idx > oldIdx).Select(a => a);
Idx 属性由接口公开。
问题是在 FindAll() 上调用 ToList() 会将整个表加载到内存中。
有没有一种方法可以在不首先加载整个表并且不丢失通用实现的情况下执行 Where ?
这里的想法是我想对所有“可排序”的实体执行一些常见的更新操作。为此,更新方法需要是通用的才能处理各种类,但是我需要接口来公开必要的字段......如果有更好的方法(可能有),请告诉我. :-)