C# 实体框架、存储过程和导航属性
我有一个POCO类,它有两个导航属性,如下所示:C# 实体框架、存储过程和导航属性,c#,entity-framework,C#,Entity Framework,我有一个POCO类,它有两个导航属性,如下所示: public class Center : Archive { public int Id { get; set; } [MaxLength(50)] public string ExternalId { get; set; } [Required, MaxLength(150)] public string Name { get; set; } [MaxLength(255)] public string Des
public class Center : Archive
{
public int Id { get; set; }
[MaxLength(50)] public string ExternalId { get; set; }
[Required, MaxLength(150)] public string Name { get; set; }
[MaxLength(255)] public string Description { get; set; }
[MaxLength(50)] public string Address1 { get; set; }
[MaxLength(50)] public string Address2 { get; set; }
[MaxLength(50)] public string Address3 { get; set; }
[MaxLength(50)] public string Address4 { get; set; }
[MaxLength(10)] public string PostCode { get; set; }
[MaxLength(100)] public string CollectionPointContact { get; set; }
[MaxLength(50)] public string CollectionPointTelephone { get; set; }
[MaxLength(50)] public string CollectionPointFax { get; set; }
[MaxLength(255)] public string CollectionPointEmail { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
public IList<Collection> Collections { get; set; }
}
public class Company : Archive
{
public int Id { get; set; }
[Required, MaxLength(100)]
public string Name { get; set; }
public string Logo { get; set; }
[Required, MaxLength(50)]
public string Theme { get; set; }
public IList<User> Members { get; set; }
public IList<Center> Centers { get; set; }
}
public class Collection : Archive
{
public int Id { get; set; }
public int CenterId { get; set; }
[Required, MaxLength(50)] public string Reference { get; set; }
[MaxLength(255)] public string Description { get; set; }
[MaxLength(50)] public string CustomerReference { get; set; }
[MaxLength(100)] public string CustomerName { get; set; }
[MaxLength(100)] public string CustomerBusinessName { get; set; }
[MaxLength(100)] public string SupplierName { get; set; }
[Column(TypeName="Date")] public DateTime PlannedCollectionDate { get; set; }
public DateTime DeliveredDate { get; set; }
public DateTime CollectedDate { get; set; }
[MaxLength(100)] public string ReceivedBy { get; set; }
public string ReceivedBySignature { get; set; }
[MaxLength(100)] public string CollectedBy { get; set; }
public string CollectedBySignature { get; set; }
public CollectionStatus Status { get; set; }
}
起初,我使用默认的延迟加载来填充属性,但加载300行数据(包括属性)需要2秒以上的时间,这是不可接受的
我决定切换到即时加载,因为我知道通过即时加载生成的SQL将使用连接,因此理论上会更快。事实并非如此,它仍然需要大约2秒才能完成
所以我的下一个任务是尝试使用存储过程。在我的repository类中,我编写了一个通用方法:
internal class Repository<T> : IDisposable, IRepository<T> where T : class
{
private readonly DatabaseContext _context;
private readonly DbSet<T> _dbEntitySet;
public Repository(DatabaseContext context)
{
if (context == null) throw new ArgumentNullException("context");
_context = context;
_dbEntitySet = context.Set<T>();
}
public IList<T> ExecuteStoredProcedure(string storedProcedureName, IList<SqlParameter> parameters = null)
{
if (parameters == null)
return _context.Database.SqlQuery<T>($"exec { storedProcedureName }").ToList();
else
return _context.Database.SqlQuery<T>($"exec { storedProcedureName } @{ parameters[0].ParameterName }").ToList();
}
}
虽然这似乎在1s时更快,我仍然认为这是过度的,但它并没有拉进我的导航属性
我发现一篇文章解释,但我想能够为任何导航属性
我曾考虑过使用反射,但这只会增加间接成本
是否有人遇到此问题并解决了此问题,或者有更好的方法解决此问题?您可以通过使用虚拟属性来实现延迟支持,并在IQeryable上调用Include方法来组合快速加载和延迟加载相关的实体。您可以通过编写无跟踪查询来提高性能。ef将检测不到更改。您可以通过使用虚拟属性来提供延迟支持,并在iQuery上调用Include方法来组合快速加载和延迟加载,以快速加载相关实体。您可以通过编写无跟踪查询来提高性能。如果没有最初加载数据的代码,ef将检测不到更改,则无法确定是否以性能方式进行了更改。我很少推荐延迟加载,因为这通常是一个性能噩梦。调用存储过程永远不会自动填充导航属性,因为EF不会生成查询。如果您想继续执行存储过程,请告诉我,我实际上刚刚将我使用的一个非常高级的查询切换到了一个过程,因为EF没有为我生成性能查询。在您的示例中,您告诉我您处理的数据量非常小。首先,你必须先分析索引的正确使用,然后再尝试优化如果基础不稳固的话不能优化的东西。使用SQLServerManagementStudio执行查询,包括实际的查询计划,并查找索引提示。然后想想你真正需要的数据。你真的需要把完整的记录带给客户吗?预测往往会大大提高性能。如果没有最初加载数据的代码,就无法确定是否以性能方式加载数据。我很少推荐延迟加载,因为这通常是一个性能噩梦。调用存储过程永远不会自动填充导航属性,因为EF不会生成查询。如果您想继续执行存储过程,请告诉我,我实际上刚刚将我使用的一个非常高级的查询切换到了一个过程,因为EF没有为我生成性能查询。在您的示例中,您告诉我您处理的数据量非常小。首先,你必须先分析索引的正确使用,然后再尝试优化如果基础不稳固的话不能优化的东西。使用SQLServerManagementStudio执行查询,包括实际的查询计划,并查找索引提示。然后想想你真正需要的数据。你真的需要把完整的记录带给客户吗?预测往往会大大提高绩效。