gpt4 book ai didi

c# EF DbContext - 从字符串动态生成对象

转载 作者:行者123 更新时间:2023-11-30 20:23:27 30 4
gpt4 key购买 nike

我想创建一个工厂类来返回 DbContext 对象,其中表名将作为字符串传递。数据库中有 100 多个表,每个表都有不同的结构/模式。

想法是在将返回 EF 中对象的方法中将 tableName 作为 string 传递,我们可以选择/更新这些记录。我在某篇文章中找到了这段代码,但对如何使用它有些困惑:

public ObjectContext Context(EntityObject entity)
{
var relationshipManager = ((IEntityWithRelationships)entity).RelationshipManager;
var wrappedOwnerProperty = relationshipManager.GetType().GetProperty("WrappedOwner", BindingFlags.Instance | BindingFlags.NonPublic);
var wrappedOwner = wrappedOwnerProperty.GetValue(relationshipManager);
var contextProperty = wrappedOwner.GetType().GetProperty("Context");
return (ObjectContext)contextProperty.GetValue(wrappedOwner);
}

我不确定这是否是我需要的。另外,我应该在 EntityObject 实体 中传递什么以及我应该在何处传递 tableName

如果有任何其他方法可以实现同样的目的,请告诉我。

最佳答案

一种简单的方法是使用 DbContext.Set() 方法,并根据字符串获取类型。

using (var db = new MyDbContext)
{
string tableName = "ApplicationUser";
var type = Assembly.GetExecutingAssembly()
.GetTypes()
.FirstOrDefault(t => t.Name == tableName);

if(type != null)
DbSet catContext = context.Set(type);
}

但是,这有一个缺点,那就是这是一个非通用 DbSet(即它是 DbSet 而不是 DbSet<T> )。

获取 Generic DbSet(允许 linq 功能)的方法是执行如下操作:

using (var db = new IdentityDbContext())
{
string tableName = "ApplicationUser";
var type = Assembly.GetExecutingAssembly()
.GetTypes().FirstOrDefault(t => t.Name == tableName);

var method = db.GetType().GetMethods()
.First(x => x.IsGenericMethod && x.Name == "Set");

MethodInfo generic = method.MakeGenericMethod(type);
var set = generic.Invoke(db, null);
}

当然 set 在这里将是一个对象,您必须以某种方式转换它,这仍然是问题的一部分。

归根结底,如果你不打算使用静态编译类型,你将不得不继续处理反射,特别是当你有泛型类型要处理时(即 DbSet<T> ,等)。您必须在某个时候将它们强制转换为静态类型才能调用这些方法,或者继续执行 MethodInfo.Invoke。

另一种选择是使用动态,但您不能将动态与 C# 扩展方法一起使用(不强制转换为具体类型),因此您又回到了没有 Linq 支持的同一条船上。

通过反射使用 Linq 是一个巨大的痛苦。

老实说,如果您有 100 个类,我会硬着头皮编写硬编码类型,或者像 CodeSmith 一样使用代码生成器为您完成。

关于c# EF DbContext - 从字符串动态生成对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28929709/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com