简体   繁体   English

检索 DbSet 的通用方法<t>来自 DbContext 并使用 Include() 方法 c#</t>

[英]Generic method to retrieve DbSet <T> from DbContext and Using Include() method c#

I made this function that retrieves all the data.我做了这个 function 来检索所有数据。

public static List<Volunteer> GetAllVolunteers()
{
    using (VolunteerPlacementSystemDBEntities1 db = new VolunteerPlacementSystemDBEntities1())
    {
        return db.Volunteers.**Include(v => v.roleForVolunteers).Include(v => v.VolunteerOffers)
                         .Include("VolunteerOffers.daysForAVolunteers")**.ToList();
    }
}

And I have this generic function that retrieves DBSet T.我有这个通用的 function 可以检索 DBSet T。

public static List<T> GetDbSet<T>() where T : class
{
    using (VolunteerPlacementSystemDBEntities1 db = new VolunteerPlacementSystemDBEntities1())
    {
        return db.GetDbSet<T>().ToList();
    }
}

Can I make a generic function that will retrieve all the data that connect to one DBSet T?我可以制作一个通用的 function 来检索连接到一个 DBSet T 的所有数据吗?

Thanks in advance.提前致谢。

Get DbSet for the T Entity Class Type from context as DbSet<T> or IQueryable<T> .获取T实体的DbSet Class 从上下文中键入DbSet<T>IQueryable<T>

On this IQueryable<T> object can perform multiple operations like Where() , Include() , orderBy() etc with help of namespace System.Linq .在这个IQueryable<T> object 上,可以在命名空间System.Linq的帮助下执行多个操作,如Where()Include()orderBy()等。

  • With Include() method, pass on required included properties.使用Include()方法,传递所需的包含属性。

  • For Parallel processing use TPL from System.Threading.Tasks对于并行处理,使用System.Threading.Tasks中的 TPL

Try this:尝试这个:

public static List<T> GetDbSet<T>(string[] includeProperties) where T : class
{
    using (VolunteerPlacementSystemDBEntities1 db = new VolunteerPlacementSystemDBEntities1())
    {
        IQueryable<T> query = db.Set<T>();

        Parallel.ForEach(inlcudeProperties, includeProperty => {
           query.Include(includeProperty);
        });

        return query.ToList();
    }
}

Some month ago i try to do somthing like that, but i have tableName.一个月前,我尝试做类似的事情,但我有 tableName。 I leave you some detail, that you can adapt我留给你一些细节,你可以适应

You extract form context all your table and select only the ClrType corrispond with your T type.您提取表格上下文所有表和 select 只有 ClrType 与您的 T 类型相对应。

var selectedTable = contextDb.Model
            .GetEntityTypes()
            .Select(x => new TableSpecification // Custom class
            {
                TableName = x.GetTableName(),
                ClrType = x.ClrType,
                JoinTable = x.GetForeignKeys(),
                JoinTableProp = x.GetForeignKeyProperties(),
                NavigationProp = x.GetNavigations(),
                ColumnsTable = null
            })
           .Where(// where ClrType)
           .Distinct()
           .FirstOrDefault();

This is my custom class这是我的习惯 class

using Microsoft.EntityFrameworkCore.Metadata;

using System;
using System.Collections.Generic;

namespace Seac.CRM.DbInfrastructure.Model.Context;

public class TableSpecification
{
    public string TableName { get; init; }
    public Type ClrType { get; init; }
    public IEnumerable<IForeignKey> JoinTable { get; init; }
    public IEnumerable<IProperty> JoinTableProp { get; init; }
    public IEnumerable<INavigation> NavigationProp { get; init; }
    public IEnumerable<IProperty> ColumnsTable { get; init; }
}

then you can extract all your reference property然后您可以提取所有参考属性

var joinLookup = selectedTable.JoinTable.GetLookupForeignKey();

foreach (var lookup in joinLookup)
   queryable = queryable.Include(lookup.PrincipalEntityType.Name.Split(".").Last());

I wish that can help you.我希望这可以帮助你。

*** EDIT ***编辑

If you need a custom include of T you can use IIncludableQueryable<T, object>>如果你需要自定义包含 T 你可以使用IIncludableQueryable<T, object>>

public static List<T> GetDbSet<T>(IIncludableQueryable<T, object>> include = null) where T : class
{
    using (VolunteerPlacementSystemDBEntities1 db = new VolunteerPlacementSystemDBEntities1())
    {
        IQueryable<T> query = db.Set<T>();

        if (includesFunc is not null)
            query = includesFunc(query);

        return query.ToList();
    }
}

Thanks to everyone who tried to help me.感谢所有试图帮助我的人。 This is the solution that worked for me.这是对我有用的解决方案。

  public static List<T> GetDbSetWithIncludes<T>(string[] includes) where T : class
    {
        using (VolunteerPlacementSystemDBEntities1 db = new VolunteerPlacementSystemDBEntities1())
        {
            db.Configuration.LazyLoadingEnabled = false;
            return IncludeMultiple<T>(db.GetDbSet<T>(), includes).ToList();
        }
    }


 public static IQueryable<T> IncludeMultiple<T>(IQueryable<T> query, string[] includes)where T : class
        {
            if (includes != null)
            {
                query = includes.Aggregate(query, (current, include) =>
                current.Include(include));
            }
            return query;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM