【发布时间】:2016-02-29 15:49:54
【问题描述】:
我知道已经有人问过这个问题,但我找不到令我满意的答案。我要做的是根据类型名称检索特定的DbSet<T>。
我有以下:
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyDllAssemblyName")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyCallingAssemblyName")]
class MyDbContext : DbContext {
public DbSet<ModelA> A { get; set; }
public DbSet<ModelB> B { get; set; }
public dynamic GetByName_SwitchTest(string name) {
switch (name) {
case "A": return A;
case "B": return B;
}
}
public dynamic GetByName_ReflectionTest(string fullname)
{
Type targetType = Type.GetType(fullname);
var model = GetType()
.GetRuntimeProperties()
.Where(o =>
o.PropertyType.IsGenericType &&
o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>) &&
o.PropertyType.GenericTypeArguments.Contains(targetType))
.FirstOrDefault();
if (null != model)
return model.GetValue(this);
return null;
}
}
无论是通过简单的开关还是反射,我都可以轻松获取类型本身。但是,我需要将类型作为动态返回,因为我不知道它将是什么 DbSet 类型。 然后在同一个程序集中的其他地方,我这样使用它:
// MyDbContext MyDbContextInstance..
var model = MyDbContextInstance.GetByName_SwitchTest("A");
var record1 = model.FirstOrDefault(); // It crashes here with RunTimeBinderException
此时model 包含InternalDbSet<ModelA> 类型的实例。从那里,我对 model 对象的任何使用都会得到 RunTimeBinderException :
“Microsoft.Data.Entity.Internal.InternalDbSet”不包含“FirstOrDefault”的定义
在网上调查,我发现一个blog post 解释说(dixit他的博客):
调用 FirstOrDefault() 失败的原因是类型 模型的信息在运行时不可用。不是的原因 可用是因为匿名类型不是公共的。当方法 正在返回该匿名类型的实例,它正在返回一个 System.Object 引用匿名类型的实例 - 一个 主程序无法获取其信息的类型。
然后他指出了一个解决方案:
解决方案其实很简单。我们所要做的就是敞开心扉 ClassLibrary1 项目的 AssemplyInfo.cs 并添加以下内容 行到它:
[assembly:InternalsVisibleTo("assembly-name")]
我确实在我的代码上尝试过这个解决方案,但它不起作用。有关信息,我有一个 asp.net 5 解决方案,其中两个程序集在 dnx dotnet46 上运行。一个应用程序和一个包含我所有模型和 DbContext 的 dll。我所做的所有相关调用都位于 dll 上。
这个解决方案有机会工作吗? 我错过了什么吗? 任何指针将不胜感激?
提前致谢
[编辑]
我尝试返回IQueryable<dynamic> 而不是dynamic,我可以执行基本查询model.FirstOrDefault(); 但最重要的是我也希望能够过滤一个字段:
var record = model.FirstOrDefault(item => item.MyProperty == true);
【问题讨论】:
-
如何将动态更改为 IEnumerable
? -
我确实尝试过类似的事情(更改为 IQueryable
),即使我可以做一些像 model.FirstOrDefault()这样的查询,它也不允许我做像model.FirstOrDefault(item => item.MyProperty == true)这样的事情。这会降低事物的实用性。 -
我也遇到了同样的问题。你有没有达成决议的机会?
-
嗨@Asryael,不幸的是我还没有找到合适的解决方案,由于时间不够,我不得不想出一个在我的案例场景中可以正常工作的替代解决方案(发布在下面)。希望这可以帮助你。
-
这不起作用
var mydbset= this.Set(typeof(SomeEntity));
标签: c# .net asp.net-mvc-5 entity-framework-core