C# 获取DbContext';s DbSet<;T>;其中T是可变的

C# 获取DbContext';s DbSet<;T>;其中T是可变的,c#,entity-framework,dbcontext,dbset,C#,Entity Framework,Dbcontext,Dbset,我有一个DbContext,看起来有点像这样: class MyDbContext: DbContext { public DbSet<Class1> Set1 {get;set;} public DbSet<Class2> Set2 {get;set;} ... } public class XmlNode { public Func<BaseClass> CreateEntity { get; set; } ...

我有一个DbContext,看起来有点像这样:

class MyDbContext: DbContext
{
    public DbSet<Class1> Set1 {get;set;}
    public DbSet<Class2> Set2 {get;set;}
    ...
}
public class XmlNode
{
    public Func<BaseClass> CreateEntity { get; set; }
    ...
}

public static Dictionary<string, XmlNode> Nodes = new Dictionary<string, XmlNode>()
{
    ["Tag1"] = new XmlNode()
    {

        CreateEntity = () => new Class1(),
    }

    ...
}
类MyDbContext:DbContext
{
公共数据库集Set1{get;set;}
公共数据库集Set2{get;set;}
...
}
其中1班,2班…:基类
问题是我正在从xml读取数据,我使用的字典如下所示:

class MyDbContext: DbContext
{
    public DbSet<Class1> Set1 {get;set;}
    public DbSet<Class2> Set2 {get;set;}
    ...
}
public class XmlNode
{
    public Func<BaseClass> CreateEntity { get; set; }
    ...
}

public static Dictionary<string, XmlNode> Nodes = new Dictionary<string, XmlNode>()
{
    ["Tag1"] = new XmlNode()
    {

        CreateEntity = () => new Class1(),
    }

    ...
}
公共类XmlNode
{
public Func CreateEntity{get;set;}
...
}
公共静态字典节点=新字典()
{
[“Tag1”]=新的XmlNode()
{
CreateEntity=()=>new Class1(),
}
...
}
然后我必须将读取的实体与现有的表进行比较,并可能添加它。但是我无法找到一种方法来获得合适的表,而不为我拥有的每个类生成不同的函数。有没有一种方法可以在类是变量的情况下获取DbSet 您只需检查它是否存在,然后在检查后获取DBset

if(Exists<yourentity>())
{
   ... TEntity exist
}
if(Exists())
{
…不稳定存在
}
从链接

public bool Exists<TEntity>() where TEntity : class
{
    string entityName = typeof(TEntity).Name;
    ObjectContext objContext = ((IObjectContextAdapter)this).ObjectContext;
    MetadataWorkspace workspace = objContext.MetadataWorkspace;
    return workspace.GetItems<EntityType>(DataSpace.CSpace).Any(e => e.Name == entityName);
}
public bool Exists(),其中tenty:class
{
字符串entityName=typeof(tenty).Name;
ObjectContext objContext=((IOObjectContextAdapter)this).ObjectContext;
MetadataWorkspace=objContext.MetadataWorkspace;
返回workspace.GetItems(DataSpace.CSpace).Any(e=>e.Name==entityName);
}

您的数据上下文所派生的
DbContext
有一个名为
Set(Type t)
的方法,该方法接受类型,可以从字符串创建类型

对于您描述的场景,您可以通过以下方式从XML中的字符串创建
DbSet

var typeName = "Some.Namespace.AndType";
DbSet t = Set(Type.GetType(typeName));

请注意,不能使用linq或lambda表达式查询结果对象,除非将其强制转换为类型化的
DbSet
或使用类似
System.linq.Dynamic
的库,该库允许调用
t.AsQueryable().Where(“SomeProperty=@value”),但这应该可以让您开始。

泛型类型参数可以变为变量的唯一方法是在另一个泛型方法/类型中。不过,您仍然必须使用已知类型调用该方法。如果您在运行时之前不知道所需的类型,则需要使用反射。我尝试使用反射,可以获取DbSet属性的值,但随后需要搜索匹配的记录,并可能添加一个新记录,但由于GetValue返回对象,因此无法执行此操作。强制转换不起作用,因为无法强制转换(DbSet)DbSet一旦开始使用反射,就必须继续使用它,例如,如果使用反射调用返回对象的方法,则必须使用该对象上的反射来获取属性值,等等。我知道Set方法,但不知道如何使其可查询。使用AsQueryable有什么缺点吗?如果没有,您的解决方案就完美地工作了。如果有帮助,请将其标记为答案。请记住,因为DbSet已经实现了IQueryable,所以此调用可以将查询转换为表达式树,在您的情况下,还可以转换为SQL。