我正在尝试替换连接并使用include但我不知道该怎么做:
IRepository<Call> callRepository =
ObjectFactory.GetInstance<IRepository<Call>>();
IRepository<Reason> reasonRepository =
ObjectFactory.GetInstance<IRepository<Reason>>();
IRepository<SimTask.Domain.Business.Entities.System.Company>
companyRepository = ObjectFactory.GetInstance<IRepository<SimTask.Domain.
Business.Entities.System.Company>>();
IQueryable<CallsListItem> x =
from call in callRepository.GetQuery()
join reason in reasonRepository.GetQuery() on call.ReasonId equals reason.Id
join company in companyRepository.GetQuery() on call.CompanyId equals company.CompanyId
where call.CompanyId == companyId &&
(!isClosed.HasValue || call.IsClosed.Equals(isClosed.Value))
select new CallsListItem()
{
CallId = call.Id,
Description = call.Description,
CloseDateTime = call.CloseDateTime,
IsClosed = call.IsClosed,
OpenDateTime = call.OpenDateTime,
PhoneNumber = call.PhoneNumber,
ReasonName = reason.Name,
CompanyName = company.CompanyName
};
IRepository由以下人员实施:
public class EFRepository<T> : IRepository<T> where T : class
{
ObjectContext _context;
IObjectSet<T> _objectSet;
private ObjectContext Context
{
get
{
if (_context == null)
{
_context = GetCurrentUnitOfWork<EFUnitOfWork>().Context;
}
return _context;
}
}
private IObjectSet<T> ObjectSet
{
get
{
if (_objectSet == null)
{
_objectSet = this.Context.CreateObjectSet<T>();
}
return _objectSet;
}
}
public TUnitOfWork GetCurrentUnitOfWork<TUnitOfWork>() where TUnitOfWork : IUnitOfWork
{
return (TUnitOfWork)UnitOfWork.Current;
}
public IQueryable<T> GetQuery()
{
return ObjectSet;
}
public IEnumerable<T> GetAll()
{
return GetQuery().ToList();
}
public IEnumerable<T> Find(Func<T,bool> where)
{
return this.ObjectSet.Where<T>(where);
}
public T Single(Func<T,bool> where)
{
return this.ObjectSet.Single<T>(where);
}
public T First(Func<T,bool> where)
{
return this.ObjectSet.First<T>(where);
}
public void Delete(T entity)
{
this.ObjectSet.DeleteObject(entity);
}
public void Add(T entity)
{
this.ObjectSet.AddObject(entity);
}
public void Attach(T entity)
{
this.ObjectSet.Attach(entity);
}
public void SaveChanges()
{
this.Context.SaveChanges();
}
}
为什么包括更好然后加入?
我该怎么办?
答案 0 :(得分:2)
Include
是热切的加载,它填充实际实体中的导航属性,而无需投影到非实体类型 - 这不能通过连接实现。此外,Include
使用左外连接,而您的查询使用内连接,因此您不会获得没有相关实体的实体。
在EFv1和EFv4中,Include
是ObjectQuery
的方法。我使用EFv4.1编写了this answer,其中包含IQueryable<T>
的扩展方法以及带有lambda表达式的Includes
。您可以try it - 它只是您将链接到项目的另一个库,您仍然可以使用EFv4。
将Include包装在自定义方法中的原因不是在上层引入依赖于EF。如果您不下载EFv4.1,可以使用:
public static IQueryable<T> IncludeMultiple<T>(this IQueryable<T> query, params string[] includes)
where T : class
{
if (includes != null)
{
var objectQuery = query as ObjectQuery;
if (objectQuery == null)
{
throw new InvalidOperationException("...");
}
objectQuery = includes.Aggregate(objectQuery,
(current, include) => current.Include(include));
}
return objectQuery;
}
两种方法(EFv4和EFv4.1)的最大缺点是转换为ObjectQuery(EFv4.1在内部执行) - 在单元测试中,这可能是一个严重的问题,您无法使用真正的查询。