Entity framework中 include 扩展:
var xList = repository.GetQuery<Site>().Include(s => s.TaskGroups.Select(sd => sd.TaskLists)).ToList<Site>();
如果用实体框架自带的扩展, 请注意添加命名空间System.Data.Entity的引用。
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters")] public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, Expression<Func<T, TProperty>> path)
where T : class;
01.
public static IQueryable<T> Include<T>(this ObjectSet<T> source, Expression<Func<T, object>> path) where T : class { StringBuilder pathBuilder = new StringBuilder(); MemberExpression pro = path.Body as MemberExpression; while (pro != null) { //Exprssion有點像鏈結串列,從Statemant的後方往前連結,如: x=> x.Customer.CustomerAddress //path.Body是CustomerAddress //CustomerAddress的Expression是Customer //Customer的Expression是x pathBuilder.Insert(0, "." + pro.Member.Name); pro = pro.Expression as MemberExpression; } return source.Include(pathBuilder.ToString(1, pathBuilder.Length-1)); }
02.
public static class ObjectQueryExtensions { public static ObjectQuery<T> Include<T>(this ObjectQuery<T> query, Expression<Func<T, object>> selector) { string path = new PropertyPathVisitor().GetPropertyPath(selector); return query.Include(path); } class PropertyPathVisitor : ExpressionVisitor { private Stack<string> _stack; public string GetPropertyPath(Expression expression) { _stack = new Stack<string>(); Visit(expression); return _stack.Aggregate( new StringBuilder(), (sb, name) =>(sb.Length > 0 ? sb.Append(".") : sb).Append(name) ).ToString(); } protected override Expression VisitMember(MemberExpression expression) { if (_stack != null) _stack.Push(expression.Member.Name); return base.VisitMember(expression); } protected override Expression VisitMethodCall(MethodCallExpression expression) { if (IsLinqOperator(expression.Method)) { for (int i = 1; i < expression.Arguments.Count; i++) { Visit(expression.Arguments[i]); } Visit(expression.Arguments[0]); return expression; } return base.VisitMethodCall(expression); } private static bool IsLinqOperator(MethodInfo method) { if (method.DeclaringType != typeof(Queryable) && method.DeclaringType != typeof(Enumerable)) return false; return Attribute.GetCustomAttribute(method, typeof(ExtensionAttribute)) != null; } } }
最原始的写法:
// Define a LINQ query with a path that returns // orders and items for a contact. var contacts = (from contact in context.Contacts .Include("SalesOrderHeaders.SalesOrderDetails") select contact).FirstOrDefault();
Contacts.SalesOrderHeaders.SaleOrderDetails 将某联系人全部的订单头和明细都列出来了。