![](/img/trans.png)
[英]If I have a List<T>, is there any advantage of using an IEnumerable<T> when looping through the list?
[英]Can I take advantage of List<T> functions Remove(T) and Insert(Int32, T) when using UpdateRange(IEnumerable<T>)?
我正在尝试实现 controller 方法来重新排序需要使用 EF Core 保存在数据库中的图像索引。
我有以下 controller 方法:
[HttpPost]
public async Task<JsonResult> ReorderImage(int p_iImageID, int p_iNewOrderIndex)
{
if (p_iImageID <= 0)
return Json(new { Status = "Error", Message = $"Unable to retrieve item image with ID of {p_iImageID}" });
ItemImage l_oItemImage = await _Context.ItemImages.FirstOrDefaultAsync(l_oImage => l_oImage.ID == p_iImageID);
if (l_oItemImage.IsNull())
return Json(new { Status = "Error", Message = $"Unable to retrieve item image with ID of {p_iImageID}" });
List<ItemImage> l_oItemImages = await _Context.ItemImages.Where(l_oImage => l_oImage.ItemID == l_oItemImage.ItemID)
.OrderBy(l_oImage => l_oImage.Order)
.ToListAsync();
l_oItemImages.Remove(l_oItemImage);
l_oItemImages.Insert(p_iNewOrderIndex, l_oItemImage);
foreach(ItemImage l_oImage in l_oItemImages)
{
l_oImage.Order = l_oItemImages.IndexOf(l_oImage);
if (l_oItemImages.IndexOf(l_oImage) == 0)
l_oImage.IsPrimary = true;
else
l_oImage.IsPrimary = false;
l_oImage.Uri = _AzureBlobStorage.GetBlobUri(_ItemImageAzureBlobContainerName, l_oImage.GetFileName());
}
_Context.ItemImages.UpdateRange(l_oItemImages);
await _Context.SaveChangesAsync();
return Json(l_oItemImages)
}
调用UpdateRange()
和随后的SaveChangesAsync()
时l_oItemImages
的顺序和数据对我来说似乎是正确的。
我一直在看这个问题,它提到不创建新类和使用UpdateRange()
。 这似乎有点不同,但我可以看到这可能是我的问题。
我有这个问题是因为我使用Remove(l_oItemImage)
然后Insert(p_iNewOrderIndex, l_oItemImage)
操作列表的对象吗? 还是因为我在抓取项目图像时使用ToListAsync()
开始?
编辑:尝试用Update(l_oItemImage)
代替UpdateRange(l_oItemImages)
,结果相同。 添加了显示附加实体的 QuickWatch 图像,两者均正确显示State = Modified
以及int Order
和bool IsPrimary
属性的预期更改值。
编辑 2:添加了 QuickWatch 数据的图像,并在实体上突出显示了更改的属性。
是的,您应该能够利用 List 方法,但是我认为UpdateRange
对于这个常见任务来说是不必要的,这是一个替代实现。
您可能需要考虑类似以下内容,而不是为序列实体的子集重新分配序列:
public async Task SetSequenceAsync(int forPageComponentId, int newSequence)
{
var infoAboutItemWereChangingSequenceFor = await context.PageComponents
.Where(x => x.Id == forPageComponentId)
.Select(x => new {
OriginalSequence = x.Sequence, // I need to know it's current sequence.
x.PageId // I need to only adjust sequences for items that have the same PageId, so I need to know what the pageId is for the item we're targeting.
}).FirstOrDefaultAsync();
// Get just the data we want to modify, we're going to include the item we're targeting so this list is inclusive of it.
// Including the item we're changing to make logic below a little mor consise instead of managing the list and the item we're targeting
// seperately.
var allItemsWithSequenceThatWillChange = await context.PageComponents
.Where(x =>
x.PageId == infoAboutItemWereChangingSequenceFor.PageId // Only those items sharing the same page Id.
// Only those items we need to change the sequence for.
&& x.Sequence >= Math.Min(infoAboutItemWereChangingSequenceFor.OriginalSequence, newSequence)
&& x.Sequence <= Math.Max(infoAboutItemWereChangingSequenceFor.OriginalSequence, newSequence)
)
.Select(x =>
new PageComponent() // The type of object EF knows about.
{
// The Primary key, so Entity Framework knows what record to change the sequence on.
Id = x.Id,
// The sequence value we need to change.
Sequence = x.Sequence
}
).ToListAsync();
// Set the sequence of the item we're targeting.
allItemsWithSequenceThatWillChange
.Where(x => x.Id == forPageComponentId)
.First()
.Sequence = newSequence;
// Now update the sequence on the other items (excluding the target item)
foreach (var item in allItemsWithSequenceThatWillChange.Where(x => x.Id != forPageComponentId))
{
// Either increment or decrement the sequence depending on how the original item was moved.
item.Sequence += infoAboutItemWereChangingSequenceFor.OriginalSequence > newSequence ? 1 : -1;
// Add any other property changes here.
}
// Save changes.
await context.SaveChangesAsync();
}
此外,为了简化您的 ItemImage object,我注意到您有一个明显的数据库持久属性“IsPrimary” - 您可能希望将其更改为在实体甚至数据库级别上计算,例如:
public class ItemImage {
// ... Other Properties ...
public int Order { get; set; }
public bool IsPrimary {
get => Order == 0;
set {}
}
}
对于您可以查询的 MSSQL 数据库中的计算列,添加到您的 DbContext OnModelCreating:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity(typeof(ImageObject)).Property("IsPrimary").HasComputedColumnSql("CASE WHEN [Order] = 0 THEN 1 ELSE 0 END");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.