我一直在使用POCO First方法和Entity Framework。基本上,我遵循了Steve Sanderson在他的书“Pro ASP.NET MVC 3 Framework”中描述的模式,使用DI容器和DbContext类来连接SQL Server。
由于SQL Server中的底层表包含不同应用程序使用的非常大的数据集,因此我不得不为我应用程序中需要的实体创建视图:
class RemoteServerContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Order> Orders { get; set; }
public DbSet<Contact> Contacts { get; set; }
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>().ToTable("vw_Customers");
modelBuilder.Entity<Order>().ToTable("vw_Orders");
...
}
}
我发现这对于我的大部分需求来说都运作良好。
但我有一个问题,某些视图中包含了大量的数据,因此当我调用类似以下的内容时:
var customers = _repository.Customers().Where(c => c.Location == location).Where(...);
看起来它正在返回整个数据集,这可能需要一些时间,然后LINQ查询才能将集合减少到我所需的内容。当条件仅适用于少数记录时,从SQL服务器获取整个数据集似乎非常低效。
我已经尝试通过使用存储过程来解决这个问题,例如
public IEnumerable<Customer> CustomersThatMatchACriteria(string criteria1, string criteria2, ...) //or an object passed in!
{
return Database.SqlQuery<Customer>("Exec pp_GetCustomersForCriteria @crit1 = {0}, @crit2 = {1}...", criteria1, criteria2,...);
}
虽然这种方法速度更快,但问题在于它不返回DbSet,因此我失去了对象之间的所有连接性。例如,即使我包括它们的ID,我也无法引用任何关联的对象,如订单或联系人,因为返回类型是“Customers”的集合而不是它们的DbSet。
有没有更好的方法来获取SQL Server进行查询,以便我不会传递大量未使用的数据?
_repository.Customers().Where(predicate)
或(如果它不再是IQueryable)编写一个单独的函数,使用context.CreateQuery<Customer>("Customers").Where(predicate)
,并在末尾调用.ToList()
的可能性。它应该构造一个漂亮的、优化的表达式。 - Patryk Ćwiek