我的问题的答案可能微不足道,但我无法弄清楚如何去做。
假设我们有以下情况:
Employee
public class Employee
{
public int ID { get; set;}
public IEnumerable<Department> Departments { get; set;}
public IEnumerable<JobCandidate> Candidates { get; set;}
}
(相关类与此示例无关)
EmployeeService
public class EmployeeService
private RepoTestEntities1 _Database;
public EmployeeService(RepoTestEntities1 database)
{
_Database = database;
}
public IQueryable<DomainModels.Employee> GetSalariedEmployeesByDepartmentName(string departmentName)
{
_Database.Configuration.LazyLoadingEnabled = false;
return _Database.Employee
.Include(e => e.EmployeeDepartmentHistory)
.Include(e => e.JobCandidate)
.Include(e => e.EmployeeDepartmentHistory.Select(his => his.Department))
.AsNoTracking()
.WhereDepartmentName(departmentName)
.WhereSalariedFlag(true)
.Select(e => CreateEmployee(e));
}
private DomainModels.Employee CreateEmployee(Employee e)
{
[...] (transform to domain)
}
WhereDepartmentName
WhereSalariedFlag
和IQueryable<Employee>
被实现为EmployeeService
的扩展方法。
假设我需要更多方法,从DbContext检索Employees,我不想使用Lazy加载。
反复调用所有这些内容是多余的,容易出错且乏味。您是否知道一种优雅的方式,即始终包含{{1}}的所有方法所需的属性?
策略模式可能是一种可行的方法吗?
答案 0 :(得分:0)
如果您确实需要包括所有导航属性,则可以使用这段代码。
如果您需要同时加载集合(并非总是一个好主意),则可以删除代码中的continue语句。
上下文就是您的上下文(如果在上下文中插入此代码,则为this
public IQueryable<T> IncludeAllNavigationProperties<T>(IQueryable<T> queryable)
{
if (queryable == null)
throw new ArgumentNullException("queryable");
ObjectContext objectContext = ((IObjectContextAdapter)Context).ObjectContext;
var metadataWorkspace = ((EntityConnection)objectContext.Connection).GetMetadataWorkspace();
EntitySetMapping[] entitySetMappingCollection = metadataWorkspace.GetItems<EntityContainerMapping>(DataSpace.CSSpace).Single().EntitySetMappings.ToArray();
var entitySetMappings = entitySetMappingCollection.First(o => o.EntityTypeMappings.Select(e => e.EntityType.Name).Contains(typeof(T).Name));
var entityTypeMapping = entitySetMappings.EntityTypeMappings[0];
foreach (var navigationProperty in entityTypeMapping.EntityType.NavigationProperties)
{
PropertyInfo propertyInfo = typeof(T).GetProperty(navigationProperty.Name);
if (propertyInfo == null)
throw new InvalidOperationException("propertyInfo == null");
if (typeof(System.Collections.IEnumerable).IsAssignableFrom(propertyInfo.PropertyType))
continue;
queryable = queryable.Include(navigationProperty.Name);
}
return queryable;
}