我看到一种非常奇怪的行为,我花了两天的时间试图弄清楚发生了什么。任何帮助表示赞赏。
所有问题。我正在使用实体框架禁令和存储库模式。如果我没有指定DbContext的具体类型,我将获得OutOfMemoryExpecption。但是,指定具体类型确实破坏了我试图实现的通用模式。有谁知道为什么会发生这种情况,ConcreteDbContext.Models和DbContext.Set之间的区别是什么?
注意:我正在处理一个大约200万个recrods的数据集。
OutOfMemoryException场景
public interface IRepository<T> where T : class
{
T Add(T entity);
T Update(T entity);
T Delete(T entity);
IEnumerable<T> GetAll();
...
}
public class MyDbContext : DbContext
{
public MyDbContext (string connectionString)
: base(connectionString)
{
//Intentionally Left Blank
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual IDbSet<MyModel> Models{ get; set; }
}
public abstract class EfRepositoryBase<T> : IRepository<T>
where T : class
{
private readonly DbSet<T> _dbSet;
protected EfRepositoryBase(DbContext context)
{
_dbSet = context.Set<T>();
}
protected IDbSet<T> Table
{
get { return _dbSet; }
}
...
}
public class MyRepository : EfRepositoryBase<MyModel>, IMyRepository
{
public MyRepository (DbContext context)
: base(context)
{
}
//Example Method
public IList<DateTime> DoStuff(DateTime start, int lookforward)
{
var startRangeEnd = start.AddDays(lookforward);
var startRange =
Table.AsNoTracking()
.Where(s => s.eventDate >= start && s.eventDate <= startRangeEnd)
.OrderBy(o => o.eventDate)
.Select(s => s.eventDate).Distinct();
return startRange.ToList();
}
.... //More methods that do Linq Queries
}
工作场景 请注意,在工作场景中我需要在我的EfBaseRepository中返回Context然后在我的实现中将其转换为具体类型以访问Models Dbset 。 (我也可以在EFBaseRepository中返回MyDbContext,但我试图避免使用具体的MyDbContext类型。)
public interface IRepository<T> where T : class
{
T Add(T entity);
T Update(T entity);
T Delete(T entity);
IEnumerable<T> GetAll();
...
}
public class MyDbContext : DbContext
{
public MyDbContext (string connectionString)
: base(connectionString)
{
//Intentionally Left Blank
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual IDbSet<MyModel> Models{ get; set; }
}
public abstract class EfRepositoryBase<T> : IRepository<T>
where T : class
{
private readonly DbSet<T> _dbSet;
private readonly DbContext _dbContext;
protected EfRepositoryBase(DbContext context)
{
_dbSet = context.Set<T>();
}
protected DbContext Table
{
get { return _dbContext; }
}
...
}
public class MyRepository : EfRepositoryBase<MyModel>, IMyRepository
{
public MyRepository (DbContext context)
: base(context)
{
}
protected MyDbContext Ctx
{ get { return Table as MyDbContext; } }
//Example Method
public IList<DateTime> DoStuff(DateTime start, int lookforward)
{
var startRangeEnd = start.AddDays(lookforward);
var startRange =
Ctx.Models.AsNoTracking()
.Where(s => s.eventDate >= start && s.eventDate <= startRangeEnd)
.OrderBy(o => o.eventDate)
.Select(s => s.eventDate).Distinct();
return startRange.ToList();
}
.... //More methods that do Linq Queries
}
答案 0 :(得分:1)
这是Unbounded result set
的正常行为。无界结果集是查询未明确限制查询返回结果数的位置。 more info here
要解决此问题,您需要使用Take
和Skip
方法开始分页结果:
const int pageSize = 25;
var list = ctx.Table1.OrderBy(g => g.Id)
.Select(g => ....)
.Skip(pageSize * pageNumber)
.Take(pageSize);