c# Linq -如何使用一个类型的集合创建两个类型的集合



我有一个List<Category>

public partial class Category
{
public int CategoryId { get; set; }
public string? Name { get; set; }
public int? ImageId { get; set; }
public virtual ProductImage? Image { get;
set; }
public virtual ICollection<Product> Products { get; } = new List<Product>();
}

,我想用一个linq表达式创建一个List<(string, Image)>。我该怎么做呢?

使用多个指令进行操作将看起来像这样:

List<Category> CategoriesWithImages = Context.Categories.Include(c => c.Image).ToList();
List<(string, Image)> values = new List<(string, Image)>();
CategoriesWithImages.ForEach(c => values.Add((c.Name, Image.FromStream(new MemoryStream(c.Image.Image)))));

有更好的方法吗?

编辑:不幸的是,我不得不使用Include()方法从另一个表加载图像

你可以这样做:

List<(string, Image)> values = CategoriesWithImages
.Select(c => new ValueTuple<string, Image>(c.Name, Image.FromStream(new MemoryStream(c.Image.Image))))
.ToList();

使用记录是另一种选择(需要c# 9+):

List<ImageData> values = CategoriesWithImages
.Select(c => new ImageData(c.Name, Image.FromStream(new MemoryStream(c.Image.Image))))
.ToList();
record struct ImageData(string Name, Image Image);

注意:结构型记录需要c# 10+

现在Context.Categories.Include(c => c.Image)在内存中加载了整个CategoriesImages表。这是浪费的

更好的方法是从数据库中只检索必要的字段,并且使用Image。与System.Drawing名称空间中的所有类型一样,这个类仅用于使用GDI+在桌面屏幕上绘图,并且使用有限的操作系统范围资源。这就是为什么没有Image.FromBytes的原因——映像应该存储在本地磁盘上,或者从应用程序的资源中加载。

从评论来看,似乎有大约20个缩略图,每个15KB,显示在Windows窗体应用程序中。

LINQ查询可以只加载名称和图像作为byte[]数组,在字典或列表中,这取决于使用:

record MyImage(string Name,byte[] Content);
...
var categoryThumbnails=await Context.Categories
.ToListAsync(new MyImage(c.Name,c.Image.Image));

Dictionary<string,byte[]> categoryThumbnails=await Context.Categories
.ToDictionaryAsync(c=>c.Name,c=>c.Image.Image));

EF Core将在Categories和Image表之间生成必要的join,并且只加载NameImage属性。

此时,一个好主意是将图像存储在本地,例如在临时文件夹中,并使用图像派生的Bitmap类和Bitmap(string)构造函数从磁盘加载它们。

相关内容

  • 没有找到相关文章

最新更新