如何将动态实体设置为 dbcontext Entity Framework Core?

Posted

技术标签:

【中文标题】如何将动态实体设置为 dbcontext Entity Framework Core?【英文标题】:How to set dynamic entity to dbcontext Entity Framework Core? 【发布时间】:2018-06-09 13:02:54 【问题描述】:

我得到了一个方法,它接收一个像字符串这样的实体来返回该实体的列表。

我想要的是动态设置实体并返回结果。

我需要的是这样的:

DbContext.Set <Type.GetType("Entity")>().Select(e => e);

这是我得到的错误:

也许这样做是不正确的。

Set 方法来自 Entity Framework Core。

【问题讨论】:

我相信DbContext.Set(Type.GetType("Entity")... 应该可以工作 问题是我认为在 EntityFrameworkCore 中是不支持的。 对不起!但是 Set 方法来自 EntityFrameworkCore 我看到了问题,抱歉,问题是我使用的是 EntityFrameworkCore 而不是 EntityFramework 5 o 6,这是其他版本。跨度> 我刚试过这个作品,***.com/questions/48041821/… 【参考方案1】:

您可以使用 通用类型,如下所示:

DbContext.Set<T>().Select(e => e);

但是为此,您的方法应该使用泛型,如下面的示例(此代码未测试):

public Task<object> MyMethod<T>(T model)

   // some Code

您可以在此Link

了解更多信息

抱歉英语不好。 我希望它的帮助 ...

【讨论】:

【参考方案2】:

第一个 - 这是一个示例,不是针对您的特定问题的解决方案。

我的实体类

using System;
using System.Collections.Generic;
using System.Text;

namespace MyIdentityModel

    public class IdentityRole
    
        public long Id  get; set;  
        public string Name  get; set;  = null!;
        public DateTimeOffset CreatedAt  get; set; 
        public bool Active  get; set; 
        public bool Enabled  get; set; 
        public DateTimeOffset ActiveUntil  get; set; 

    

我的背景

using MyIdentityModel.Configuration;
using Microsoft.EntityFrameworkCore;
using System;

namespace MyIdentityModel


    public abstract class IdentityDbContextBase: DbContext
    

        public IdentityDbContextBase(DbContextOptions options) : base(options)
        
        

        
        public DbSet<IdentityRole> Roles  get; set;  = null!;
        

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        
            base.OnModelCreating(modelBuilder);
                        modelBuilder.ApplyConfiguration(new IdentityRoleConfiguration());
           
        
    


示例解决方案 我有3种方法

public List<TResult> GetList<TResult>(DbContext context, string entityTypeName)
    where TResult : class

    Type entityType = Type.GetType(entityTypeName); // get type of entity / MyIdentityModel.IdentityRole
    var setMethod = context.GetType().GetMethod(nameof(DbContext.Set), new Type[]  ).MakeGenericMethod(entityType); //Get Method Set<MyIdentityModel.IdentityRole>
    var dbSet = setMethod.Invoke(context, new object[]  ); // Calling context.Set<MyIdentityModel.IdentityRole>
    /* Call to another methods using reflection before calling "ToList" 
        Eg. example Where, Include, Select
        */
    var toListMethod = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(entityType); //get Extension Method "ToList<MyIdentityModel.IdentityRole>"
    var list = (List<TResult>)toListMethod.Invoke(null, new object[]  dbSet );//Calling "context.Set<MyIdentityModel.IdentityRole>.ToList<MyIdentityModel.IdentityRole>()" Method and convert to destination type if is possible.
    return list;


public List<TEntity> GetList2<TEntity>(DbContext context)
    where TEntity : class

    var setMethod = context.GetType().GetMethod(nameof(DbContext.Set), new Type[]  ).MakeGenericMethod(typeof(TEntity)); //Get Method Set<MyIdentityModel.IdentityRole>
    var dbSet = setMethod.Invoke(context, new object[]  ); // Calling context.Set<MyIdentityModel.IdentityRole>
    /* Call to another methods using reflection before calling "ToList" 
        Eg. example Where, Include, Select
        */
    var toListMethod = typeof(Enumerable).GetMethod("ToList").MakeGenericMethod(typeof(TEntity)); //get Extension Method "ToList<MyIdentityModel.IdentityRole>"
    var list = (List<TEntity>)toListMethod.Invoke(null, new object[]  dbSet );//Calling "context.Set<MyIdentityModel.IdentityRole>.ToList<MyIdentityModel.IdentityRole>()" Method and convert to destination type if is possible.
    return list;


public List<TEntity> GetList3<TEntity>(DbContext context)
    where TEntity : class

    return context.Set<TEntity>()/* Call to another methods before "ToList" */.ToList();



主程序调用。

    您需要上下文,AssemblyQualifiedName = 参数。结果的类型名称 = 类型参数

public List&lt;TResult&gt; GetList&lt;TResult&gt;(DbContext context, string entityTypeName)

    您需要上下文 = 参数。结果的类型名称 = 类型参数

public List&lt;TEntity&gt; GetList2&lt;TEntity&gt;(DbContext context)

    您需要上下文 = 参数。结果的类型名称 = 类型参数

public List&lt;TEntity&gt; GetList3&lt;TEntity&gt;(DbContext context)

Console.WriteLine("█ Result 1");
var result = GetList<MyIdentityModel.IdentityRole>(context, typeof(MyIdentityModel.IdentityRole).AssemblyQualifiedName);
Console.WriteLine(JsonSerializer.Serialize(result));
Console.WriteLine();

Console.Write("█ Result 2");
var result2 = GetList2<MyIdentityModel.IdentityRole>(context);
Console.WriteLine(JsonSerializer.Serialize(result2));
Console.WriteLine();

Console.Write("█ Result 3");
var result3 = GetList3<MyIdentityModel.IdentityRole>(context);
Console.WriteLine(JsonSerializer.Serialize(result3));
Console.WriteLine();

【讨论】:

以上是关于如何将动态实体设置为 dbcontext Entity Framework Core?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用实体框架时要重新启动 DbContext?

我应该如何编写转换数据的实体框架迁移(最好使用 DbContext)?

如何将部分更新操作从 ObjectContext 转换为 DbContext

实体框架:如何防止 dbcontext 被多个线程访问?

如何从 DBContext(实体框架核心)中的 App.config(不是 .net 核心应用程序)读取值

如何从实体框架 DbContext 收集当前的 SQL Server 会话 ID?