首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否有一种将()全部包含在dbcontext中的方法?

是否有一种将()全部包含在dbcontext中的方法?
EN

Stack Overflow用户
提问于 2015-02-12 16:38:31
回答 3查看 6.2K关注 0票数 4

当查询具有急切加载的DbContext时,需要Include("Navigation")才能填充导航属性。然而,在某些情况下,我只想简单地Include实体的所有导航属性。有没有解决这个问题的方法,或者做这个的方法?我想你可以反光,但我宁愿避免那样做。

据我所知:

代码语言:javascript
复制
var entity = db.Table.Include("Navigation1").Include("Navigation2").First();

我想要的:

代码语言:javascript
复制
var entity = db.Table.IncludeAll().First(); 
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-02-12 17:05:30

不是的。根本就没有。Entity有意让您明确说明您想要加载的内容,因为添加联接会使您的查询变得更重、更慢。这是为了保护你不受自己的伤害。如果您需要连接,那么很好,但至少当您显式地指定它们时,您将确切地知道要发生多少次,以及为什么。

票数 6
EN

Stack Overflow用户

发布于 2020-11-05 10:08:08

不管实体框架的设计者是怎么想的,我发现有一个用于递归加载所有数据库项的合法用例:创建数据库内容的快照,可以通过自动测试轻松地恢复。如果这就是您所追求的,您可能会发现这篇文章非常有趣,以及这个扩展方法:

代码语言:javascript
复制
public static class EfExtensions
{
    public static IQueryable<TEntity> IncludeAllRecursively<TEntity>(this IQueryable<TEntity> queryable, 
        int maxDepth = int.MaxValue, bool addSeenTypesToIgnoreList = true, HashSet<Type>? ignoreTypes = null)
        where TEntity : class
    {
        var type = typeof(TEntity);
        var includes = new List<string>();
        ignoreTypes ??= new HashSet<Type>();
        GetIncludeTypes(ref includes, prefix: string.Empty, type, ref ignoreTypes, addSeenTypesToIgnoreList, maxDepth);
        foreach (var include in includes)
        {
            queryable = queryable.Include(include);
        }

        return queryable;
    }

    private static void GetIncludeTypes(ref List<string> includes, string prefix, Type type, ref HashSet<Type> ignoreSubTypes, 
        bool addSeenTypesToIgnoreList = true, int maxDepth = int.MaxValue)
    {
        var properties = type.GetProperties();
        foreach (var property in properties)
        {
            var getter = property.GetGetMethod();
            if (getter != null)
            {
                var isVirtual = getter.IsVirtual;
                if (isVirtual)
                {
                    var propPath = (prefix + "." + property.Name).TrimStart('.');
                    if (maxDepth <= propPath.Count(c => c == '.')) { break; }

                    includes.Add(propPath);
                    
                    var subType = property.PropertyType;
                    if (ignoreSubTypes.Contains(subType))
                    {
                        continue;
                    }
                    else if (addSeenTypesToIgnoreList)
                    {
                        // add each type that we have processed to ignore list to prevent recursions
                        ignoreSubTypes.Add(type);
                    }

                    var isEnumerableType = subType.GetInterface(nameof(IEnumerable)) != null;
                    var genericArgs = subType.GetGenericArguments();
                    if (isEnumerableType && genericArgs.Length == 1)
                    {
                        // sub property is collection, use collection type and drill down
                        var subTypeCollection = genericArgs[0];
                        if (subTypeCollection != null)
                        {
                            GetIncludeTypes(ref includes, propPath, subTypeCollection, ref ignoreSubTypes, addSeenTypesToIgnoreList, maxDepth);
                        }
                    }
                    else
                    {
                        // sub property is no collection, drill down directly
                        GetIncludeTypes(ref includes, propPath, subType, ref ignoreSubTypes, addSeenTypesToIgnoreList, maxDepth);
                    }
                }
            }
        }
    }
}

注意:在遍历数据库项时避免循环是必不可少的。默认情况下,它是使用忽略列表ignoreSubTypes完成的:添加了每个可见类型。这可能并不总是有效的(例如,当一个项目“信件”中包含“发件人”和“收件人”两种类型的Person时)。在这种情况下,您可以尝试使用maxDepth。祝你好运,但别开枪!

票数 4
EN

Stack Overflow用户

发布于 2020-03-04 16:50:31

一个简单的选项是使用反射检查虚拟属性。

代码语言:javascript
复制
public static IQueryable<T> IncludeAlla<T>(this IQueryable<T> queryable) where T : class
{
    var type = typeof(T);
    var properties = type.GetProperties();
    foreach (var property in properties)
    {
        var isVirtual = property.GetGetMethod().IsVirtual;
        if (isVirtual)
        {
            queryable = queryable.Include(property.Name);
        }
    }
    return queryable;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28482882

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档