主要问题是,当Web应用程序启动到互联网时,当负载很高时,会引发异常,告知已经存在打开的数据读取器。
以下是我们使用的规格:
如果没有using(){}
块,是否有解决此问题的方法?这种方法的主要问题是,当关闭using块时,我无法在html视图内扩展entityframework对象的外键关系。
我还附加了一些源代码,展示了我们如何在整个应用程序中保持单个数据库上下文
public abstract class AbstractService
{
public Entities db_model
{
get
{
return DbContext.Instance.db_model;
}
}
}
public class DbContext
{
public Entities db_model = new Entities();
private static DbContext _dbContext;
public static DbContext Instance
{
get
{
if(_dbContext == null)
{
_dbContext = new DbContext();
}
return _dbContext;
}
}
}
答案 0 :(得分:0)
此答案与在ASP.NET视图中使用加载的实体的问题中提到的问题特别相关。该问题询问了一种无需using
块或无需处理DbContext
的情况下解决此问题的方法,但是我建议这样做。
原因是通常不希望在ASP.NET视图中使用Entity Framework对象,因为这些对象比普通的POCO对象要多得多。它们隐藏允许他们充当基础数据库代理的逻辑,因此它们对创建它们的DbContext
的状态具有隐藏的依赖性。
这是一个使用Employee
和Department
的EF模型使用EF模型的人为示例:
DbContext
如果在ASP.NET应用程序中使用这些模型,我将创建一些独立的模型,这些模型与ASP.NET使用的实体框架无关。例如:
public class CompanyDbContext : DbContext
{
public DbSet<Department> Departments { get; set; }
public DbSet<Employee> Employees { get; set; }
}
public class Department
{
public long Id { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
}
public class Employee
{
public long Id { get; set; }
public long DepartmentId { get; set; }
public virtual Department Department { get; set; }
}
一些注意事项:
根据MSDN文档,“ A public class DepartmentModel
{
public long Id { get; set; }
public List<EmployeeModel> Employees { get; set; }
}
public class EmployeeModel
{
public long Id { get; set; }
public long DepartmentId { get; set; }
}
代表UnitOfWork和存储库模式的组合” -https://docs.microsoft.com/en-us/dotnet/api/system.data.entity.dbcontext?redirectedfrom=MSDN&view=entity-framework-6.2.0-因此,DbContext
应该尽可能短命。
从上下文加载数据时,可以使用DbContext
-https://docs.microsoft.com/en-us/ef/ef6/querying/related-data
通常来说,出于各种原因,将“数据”层与“视图”层解耦是有意义的,其中一些原因在这里列出:https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5-这涉及EF对象和POCO模型之间的映射。
用于查询DbSet<>.Include()
的逻辑将使用EF查询数据,并使用POCO模型返回该数据,以便只有直接处理DbContext
的逻辑才涉及EF对象。 。例如:
DbContext
能够使用那些POCO模型,同时需要一些额外的样板代码,从而在 public List<DepartmentModel> GetAllDepartments()
{
using (var ctx = new CompanyDbContext())
{
// Ensure that related data is loaded
var departments = ctx.Departments
.Include(d => d.Employees);
// Manual mapping by converting into a new set of models to be used by the Views
var models = departments
.Select(d => new DepartmentModel
{
Id = d.Id,
Employees = d.Employees
.Select(e => new EmployeeModel
{
Id = e.Id,
DepartmentId = e.DepartmentId
})
.ToList(),
})
.ToList();
return models;
}
}
和ASP.NET之间实现了完全分离,从而无需使用ASP.NET视图/控制器就可以使用数据。 DbContext
的生存期或状态。
有时这看起来好像这种方法违反了“ DRY”原理,但是我要指出的是,存在EF对象和ViewModel对象可以解决不同的问题,并且ViewModel对象采用不同的形状并不少见,或者甚至需要其他不适合添加到EF类的字段/属性。
最后,以上代码使用“手动”映射,但是如果映射确实非常简单明了,则改为使用AutoMapper更为合理:Cleanest Way To Map Entity To DTO With Linq Select?