【问题标题】:How to use linq include function in generic type如何在泛型类型中使用 linq 包含函数
【发布时间】:2021-11-26 08:08:12
【问题描述】:

我想找一个员工并为这个用户获得许多项目。如何在我的查询中使用包含函数 _dbContext.Set ().FindAsync(id)

【问题讨论】:

标签: c# linq .net-core include


【解决方案1】:

我认为这将是您正在寻找的。我相当详尽地尝试将通用表示法与反射包含一起使用,但发现它很困难。 因此,FullFindAsync 方法将采用 Type 对象,您可以使用它来代替 T。然后是 param objects[] 用作搜索的关键

public static async Task<object> FullFindAsync(this DbContext context, Type entityType, params object[] keyValues)
{
    object entity = null;

    //handle an Interface as a passed in type
    if (entityType.IsInterface)
    {
        //get all Types of Models in the DbContext that implement the Interface
        var implementedModels = context.Model.GetEntityTypes()
                                    .Select(et => et.ClrType)
                                        .Where(t => entityType.IsAssignableFrom(t))
                                            .ToList();

        //loop through all Models and try to find the object via the parameters
        foreach (var modelType in implementedModels)
        { //TODO: it would be nice to not have to do a find on every Model, but only optimize if this has performance hits
            entity = await context.FindAsync(modelType, keyValues);
            if (entity != null) break;
        }
    }
    else
        //find the object, via regular Find
        entity = await context.FindAsync(entityType, keyValues);

    //didnt find the object
    if (entity == null) return null;

    //loop through all navigation properties
    foreach (var navigation in entity.GetType().GetProperties())
    {
        //skip NotMapped properties (to avoid context collection error)
        if (context.Entry(entity).Metadata.FindNavigation(navigation.Name) == null)
            continue;

        //check and load reference and collection properties
        if (typeof(IMyRootType).IsAssignableFrom(navigation.PropertyType))
            context.Entry(entity).Reference(navigation.Name).Load();
        if (typeof(IEnumerable<object>).IsAssignableFrom(navigation.PropertyType))
            context.Entry(entity).Collection(navigation.Name).Load();
    }

    return entity;
}

然后你可以像这样使用它: var myItem = await dbContext.FullFindAsync(typeof(T), someId);

我所做的是让上下文中的每个类都实现一个包含唯一键的简单接口。因此,您可能需要修改该方法以满足您的需求,但希望它可以提供帮助。 请注意,这在大型数据集上可能效率很低,因此请谨慎使用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    • 2015-03-04
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多