gpt4 book ai didi

c# - Entity Framework 查询太慢

转载 作者:行者123 更新时间:2023-11-30 17:37:26 38 4
gpt4 key购买 nike

我是 Entity Framework 的新手,喜欢它的简单性,但在速度方面遇到了一些问题。我想我可能错误地使用了延迟加载,但我很难理解它。我已经分离了我的数据模型层和业务实体层,并使用一个函数从我的数据模型中创建业务实体。在此函数中,我遍历不同的嵌套实体以创建它们相应的模型。好的,这里有一些代码已经够多了:

IM_ITEM.cs(产品数据模型)

public partial class IM_ITEM
{
public IM_ITEM()
{
this.IM_INV = new HashSet<IM_INV>();
this.IM_BARCOD = new HashSet<IM_BARCOD>();
this.IM_GRID_DIM_1 = new HashSet<IM_GRID_DIM_1>();
this.IM_GRID_DIM_2 = new HashSet<IM_GRID_DIM_2>();
this.IM_GRID_DIM_3 = new HashSet<IM_GRID_DIM_3>();
this.IM_PRC = new HashSet<IM_PRC>();
}

public string ITEM_NO { get; set; }
public string DESCR { get; set; }
// many more properties...

public virtual ICollection<IM_INV> IM_INV { get; set; }
public virtual ICollection<IM_BARCOD> IM_BARCOD { get; set; }
public virtual ICollection<IM_GRID_DIM_1> IM_GRID_DIM_1 { get; set; }
public virtual ICollection<IM_GRID_DIM_2> IM_GRID_DIM_2 { get; set; }
public virtual ICollection<IM_GRID_DIM_3> IM_GRID_DIM_3 { get; set; }
public virtual ICollection<IM_PRC> IM_PRC { get; set; }
}

业务实体创建方法:

public static ProductEntity FromEfObject(IM_ITEM obj) {
var product = new ProductEntity {
ItemNumber = obj.ITEM_NO,
StyleNumber = obj.VEND_ITEM_NO,
Title = obj.DESCR_UPR,
LongName = obj.ADDL_DESCR_1,
ShortDescription = obj.DESCR,
VendorCode = obj.ITEM_VEND_NO,
Quarter = obj.ATTR_COD_2,
Color = obj.PROF_ALPHA_2,
Markdown = obj.PRC_1,
Price = obj.REG_PRC ?? 0,
Status = obj.STAT,
DepartmentCode = obj.ATTR_COD_1,
DepartmentDigit = obj.ATTR_COD_1.Substring(0, 1),
MixAndMatch = obj.MIX_MATCH_COD,
Inventory = new Inventory(obj.IM_INV),
Sizes = new List<ProductSize>(),
Widths = new List<ProductSize>(),
Lengths = new List<ProductSize>(),
Barcodes = new Dictionary<string, string>()
};


if (obj.IM_PRC.Any()) {
var price = obj.IM_PRC.First();
product.DnsPrice2 = price.PRC_2.GetValueOrDefault();
product.DnsPrice3 = price.PRC_3.GetValueOrDefault();
}

foreach (var barcode in obj.IM_BARCOD) {
product.Barcodes.Add(barcode.DIM_1_UPR, barcode.BARCOD);
}

foreach (var size in obj.IM_GRID_DIM_1) {
product.Sizes.Add(ProductSize.FromEfObject(size));
}

foreach (var width in obj.IM_GRID_DIM_2) {
product.Widths.Add(ProductSize.FromEfObject(width));
}

foreach (var length in obj.IM_GRID_DIM_3) {
product.Lengths.Add(ProductSize.FromEfObject(length));
}

if (!product.Sizes.Any()) {
product.Sizes.Add(new ProductSize());
}

if (!product.Widths.Any()) {
product.Widths.Add(new ProductSize());
}

if (!product.Lengths.Any()) {
product.Lengths.Add(new ProductSize());
}

return product;
}

以及我检索模型的方法:

public ProductEntity GetProductById(string itemNumber, int storeNumber) {
var product = _unitOfWork
.GetProductRepository(storeNumber)
.GetQueryable()
.FirstOrDefault(p => p.ITEM_NO == itemNumber);

return product == null ? null : ProductEntity.FromEfObject(product);
}

还有 GetQueryable 方法:

internal DbSet<TEntity> DbSet;
public GenericRepository(TContext context)
{
Context = context;
DbSet = context.Set<TEntity>();
}

public virtual IQueryable<TEntity> GetQueryable()
{
IQueryable<TEntity> query = DbSet;
return query;
}

更多信息.. 我使用数据库优先建模来创建我的数据模型,而我正在测试的数据库没有大量数据。此外,我尝试在我的 GetProductById 方法中使用 .Include() 来加载(我相信是热切的),但速度进一步降低。

我做错了什么吗?或者对于这样的查询,使用 EF 会很慢。

编辑:为了防止延迟加载,我将查询更新为:

    public ProductEntity GetProductById(string itemNumber, int storeNumber) {
var product = _unitOfWork
.GetProductRepository(storeNumber)
.GetQueryable()
.Include(p => p.IM_INV.Select(i => i.IM_INV_CELL))
.Include(p => p.IM_BARCOD)
.Include(p => p.IM_GRID_DIM_1)
.Include(p => p.IM_GRID_DIM_2)
.Include(p => p.IM_GRID_DIM_3)
.Include(p => p.IM_PRC)
.FirstOrDefault(p => p.ITEM_NO == itemNumber);

return product == null ? null : ProductEntity.FromEfObject(product);
}

在跟踪时,这只给我一个比使用延迟加载耗时更长的讨厌查询 http://pastebin.com/LT1vTETb

最佳答案

您可以优化查询以避免延迟加载。在这种情况下,当您从数据库加载一个对象时,您知道您将不得不将几乎整个对象图映射到内存。无论如何,稍后您将需要查找所有这些外键 - 将所有这些作为一个查询来完成比让延迟加载完成工作更快。参见 here获取更多信息。

它应该看起来像这样:

public ProductEntity GetProductById(string itemNumber, int storeNumber) {
var product = _unitOfWork
.GetProductRepository(storeNumber)
.GetQueryable()
.Include(p => p.IM_BARCOD)
.Include(p => p.IM_GRID_DIM_1)
.Include(p => p.IM_GRID_DIM_2)
.Include(p => p.IM_GRID_DIM_3)
.Include(p => p.IM_PRC)
.FirstOrDefault(p => p.ITEM_NO == itemNumber);

return product == null ? null : ProductEntity.FromEfObject(product);
}

请注意,如果这些外键有自己的外键(即 IM_BARCOD 有一个 IM_OtherType 的集合),您还需要映射到您的 ProductEntity 模型,那么您也应该包括这些外键。你可以像这样排队:

.Include(p => p.IM_BARCOD.Select(b => b.IM_OTHERTYPE))

关于c# - Entity Framework 查询太慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38079295/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com