为了账号安全,请及时绑定邮箱和手机立即绑定

动态查找 CRUD 操作的实际 DbSet

动态查找 CRUD 操作的实际 DbSet

C#
红颜莎娜 2022-06-12 10:42:18
我在此站点上进行了搜索,但无法从我的上下文中获取实际的 DbSet。我正在尝试根据表名动态检索每个数据库集。 var dynamicdbset = GetDbSetByTableName(uploadTableName); //Dbset name is Mytables  private dynamic GetDbSetByTableName(string tableName)        {            MyEntities context = new MyEntities();            System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();            var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");            using (var db = new MyEntities())            {                var dbset = prop?.GetValue(db);                return dbset;            }        }这里的问题是它返回了一些通用数据库集,但我不能使用 linq 也不能做一个简单的操作,比如dynamicdbset.Where(t = > t.Id == 123).Single();我需要能够通过 tablename 动态获取 dbset,并且还需要以与创建数据相同的方式查询数据var value = context.MyTables.FirstorDefault()
查看完整描述

1 回答

?
神不在的星期二

TA贡献1963条经验 获得超6个赞

返回的动态DbSet实际上只是真实DbSet对象的包装器,您可以简单地将其转换为。然而,问题是,如果不使用泛型方法DbSet,就无法推断出的类型。


以下方法可行,但可能是最不可取的:


private IEnumerable<T> GetDbSetByTableName<T>(string tableName)

{

    System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();

    var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");


    using (var db = new ClearGUIEntities())

    {

        var dbset = prop?.GetValue(db);


        return new List<T>(dbset as IEnumerable<T>);

    }

}

现在,要解决这个问题,我们至少有两个选择:

  1. DbSet创建一个由所有s实现的接口(具有您需要的所有基本属性) 。这样,我们可以转换动态对象,而无需在转换时指定类型。

  2. 返回一个IEnumerable<dynamic>可以即时施放的。

选项1

public interface IBaseProperties

{

    int Id { get; set; }

    string Name { get; set; }

}


public class MyTable : IBaseProperties

{

    // Add these with either T4 templates or create partial class for each of these entities

    public int Id { get; set; }

    public string Name { get; set; }

}


private IEnumerable<IBaseProperties> GetDbSetByTableName(string tableName)

{

    System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();

    var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");


    using (var db = new ClearGUIEntities())

    {

        var dbset = prop?.GetValue(db);


        return new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);

    }

}


// ...

// Using it

// ...


var dynamicdbset = GetDbSetByTableName("MyTable");


int id = dynamicdbset.FirstOrDefault().Id;

选项 2

private IEnumerable<dynamic> GetDbSetByTableName(string tableName)

{

    System.Reflection.PropertyInfo[] properties = typeof(ClearGUIEntities).GetProperties();

    var prop = properties.FirstOrDefault(p => p.Name == tableName + "s");


    using (var db = new ClearGUIEntities())

    {

        var dbset = prop?.GetValue(db);


        return new List<dynamic>(dbset as IEnumerable<dynamic>);

    }

}


// ...


// At this point, you can basically access any property of this entity

// at the cost of type-safety

string id = dynamicdbset.FirstOrDefault().Id;

string name = dynamicdbset.FirstOrDefault().Name;

顺便说一句,强制转换List<T>是必要的,因为您使用的是using块之外的对象,此时它将被处置。


new List<IBaseProperties>(dbset as IEnumerable<IBaseProperties>);


查看完整回答
反对 回复 2022-06-12
  • 1 回答
  • 0 关注
  • 148 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号