[英]Automatically include Entity Framework properties
the answer to my question might be trivial, but I can't figure out how to do it.我的问题的答案可能微不足道,但我不知道该怎么做。
Suppose, we have the following situation:假设,我们有以下情况:
public partial class Employee
{
public int ID { get; set;}
public virtual ICollection<EmployeeDepartmentHistory> EmployeeDepartmentHistory { get; set;}
public virtual ICollection<JobCandidate> JobCandidate { get; set;}
}
Employee
Employee
(related classes don't matter for this example) (相关类对于此示例无关紧要)
public class Employee
{
public int ID { get; set;}
public IEnumerable<Department> Departments { get; set;}
public IEnumerable<JobCandidate> Candidates { get; set;}
}
EmployeeService
that applies business rules to the queryEmployeeService
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
and WhereSalariedFlag
are implemented as extension methods to IQueryable<Employee>
. WhereDepartmentName
和WhereSalariedFlag
被实现为IQueryable<Employee>
扩展方法。
Suppose I need further methods, that retrieve Employees from DbContext and I don't want to use Lazy loading.假设我需要进一步的方法,从 DbContext 检索员工,我不想使用延迟加载。
Repeatedly calling all those includes is redundant, error prone and tedious.重复调用所有这些包含是多余的、容易出错且乏味的。 Do you know an elegant way of always including the needed properties for all methods of the
EmployeeService
?您知道一种始终包含
EmployeeService
所有方法所需属性的优雅方法吗?
Might a strategy pattern be a viable approach?策略模式可能是一种可行的方法吗?
If you REALLY need to Include all the navigation properties you can use this piece of code.如果您真的需要包含所有导航属性,您可以使用这段代码。
If you need to eagerly load also collections (not always a good idea) you can delete the continue statement in the code.如果您还需要急切地加载集合(并不总是一个好主意),您可以删除代码中的 continue 语句。
Context is your context ( this
if you insert this code in your context)上下文是您的上下文(
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;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.