entity framework – 按名称获取实体

我有以下代码(示例):

public dynamic GetData(string name) { using(var ctx = GetObjectContext()) { switch (name) { case "entity1": return ctx.entity1.ToList(); case "entity2": return ctx.entity2.ToList(); ...... default: return null; } } } 

我想避免在此示例中切换。 如何按名称查找所需的实体类,调用ToList()方法并返回数据? 我可以用reflection做到这一点吗? 你能帮助我吗?

您可以使用reflection来执行此操作,但是您还需要使用generics,因为ToList()方法返回的列表类型对于每个实体类型都是不同的。

您可以通过reflection访问属性getter,如下所示:

 var enumerable = typeof([ClassNameOfContext]).GetProperty(name).GetValue(ctx, null); 

[ClassNameOfContext]是ctx是其实例的类的名称。 这在您的代码中并不明显,但您知道:-)

问题是, enumerable将是一个object ,必须转换为IEnumerable ,其中EntityType是您正在访问的实体的类型。 换句话说,它取决于您传递的名称。 如果使用generics来确定类型,则可以正确地转换对象,而不必返回dynamic甚至。

 public TEntity Get(string name) { ... 

并从上面转换线:

 var enumerable = (IEnumerable)(typeof([ClassNameOfContext]).GetProperty(name).GetValue(ctx, null)); return enumerable.ToList(); 

干得好!

附录:可以想象,你也可以摆脱字符串参数 – 在可能的情况下应该避免在字符串中使用类型或属性的名称,因为它不是类型安全的。 编译器无法识别它,并且重构等IDEfunction不会考虑它。 这里的问题是属性名称通常是实体类型名称的复数forms。 但您可以使用reflection来查找其类型与TEntity匹配的属性。 我把这作为练习:-)

你可以使用这样的代码

 private IEnumerable GetList(string connectionString, Func caster) { using (var ctx = new DbContext(connectionString)) { var setMethod = ctx.GetType().GetMethod("Set").MakeGenericMethod(typeof(T)); var querable = ((DbSet)setMethod .Invoke(this, null)) .AsNoTracking() .AsQueryable(); return querable .Select(x => caster(x)) .ToList(); } } 

要像这样打电话:

 var branchList = GetList("connectionStringName", x => (Branch)x); 

您可以删除.AsNoTracking()并删除.ToList(),然后您将获得纯IQueryable,您可以进一步查询。