无法将类型“DynamicClass1”转换为类型<T>。LINQ to Entities仅支持将EDM基元或枚举类型进行转换。

3

我花了几个小时搜索解决方案,但没有一个帖子能够帮助我。

我试图使用Linq(Entity Framework 6.0 / MVC 5.0)库从数据库中获取记录。

System.Linq.Dynamic;

以下是完整的代码:
using (var entities = new vskdbEntities())
{
     entity.DataFields = "id, stack_trace";
     _list = entities.vsk_error_log
           .OrderBy(entity.Order)
           .Select("New(" + entity.DataFields + ")")
           .Skip(entity.PageSize * entity.PageNumber)
           .Take(entity.PageSize)
           .Cast<vsk_error_log>()
           .ToList();
}

但在运行时会导致错误

类型为'System.NotSupportedException'的异常发生于EntityFramework.SqlServer.dll中,但未在用户代码中处理

附加信息:无法将类型'DynamicClass1'转换为类型'VideoKit.framework.vsk_error_log'。LINQ to Entities仅支持转换EDM基元或枚举类型。

我知道Select子句存在转换问题,但不知道如何解决这个转换问题。

更新1:

如果我尝试使用下面显示的代码,则可以正确获取数据

using (var entities = new vskdbEntities())
{
     var context = ((System.Data.Entity.Infrastructure.IObjectContextAdapter)entities).ObjectContext;

     lst = context.CreateObjectSet<vsk_error_log>().AsEnumerable().Select("new (id, stack_trace)").Cast<DynamicClass>().ToList();
 }

但是所检索到的数据类型为

System.Linq.Dynamic.DynamicClass的通用列表

而不是vsk_error_log

如果我尝试使用适当的类vsk_error_log进行转换而不是DynamicClass,那么会出现错误

无法将类型为“DynamicClass1”的对象强制转换为类型 “VideoKit.framework.vsk_error_log”。

返回的数据如屏幕截图所示:

enter image description here


我猜你需要用 .Select( x => new vsk_error_log { y = x.y, z = x.z .... }) 代替 .Cast() - DavidG
2个回答

1
为了从动态查询中获取实体本身,您需要使用it关键字,而不是new
using (var entities = new vskdbEntities())
{
     _list = entities.vsk_error_log
           .OrderBy(entity.Order)
           .Select("it") // here "it"
           .Skip(entity.PageSize * entity.PageNumber)
           .Take(entity.PageSize)
           .ToList();
}

根据您的评论,我理解您正在尝试获取部分填充的 vsk_error_log 实体。您可以使用查询的主要部分,然后将 DynamicClass 实例转换为实体。
var result = new List<vsk_error_log>();

using (var entities = new vskdbEntities())
{
    _list = entities.vsk_error_log
           .OrderBy(entity.Order)
           .Skip(entity.PageSize * entity.PageNumber)
           .Take(entity.PageSize)
           .Select("new (id, stack_trace)");

    foreach(dynamic d in _list)
    {
        result.Add(new vsk_error_log { id = d.id, stack_trace = d.stack_trace } );
    }
}

更新: 完整的代码已经实现了所需的输出。
var _list = new List<vsk_error_log>();
using (var entities = new vskdbEntities())
{
    var context = ((IObjectContextAdapter)entities).ObjectContext;
    var lst = context.CreateObjectSet<vsk_error_log>()
         .AsEnumerable()
         .Select("new(id,stack_trace)")
         .Cast<DynamicClass>()
         .Skip(entity.PageSize * (entity.PageNumber - 1))
         .Take(entity.PageSize)
         .ToList();
         foreach (dynamic d in lst)
         {
             _list.Add(new vsk_error_log { id = d.id, stack_trace = d.stack_trace });
         }
}

实际上,new也可以工作,但结果返回的是DynamicClass1列表而不是正确的列表对象。 - irfanmcsd
你能否更新你的问题,包括语法错误和引起它的查询? - Gert Arnold
好的,“它”运行正常,但它返回了所有列,如果我需要返回选定的列呢? - irfanmcsd
那么你就不能将其转换为 vsk_error_log。你会得到一个 DynamicClass,你必须对它进行操作。 - Gert Arnold
1
谢谢你的转换解决方案,它起作用了。我在你的答案中发布了完整的工作代码。之前在你的答案中编写的代码仍然存在我在标题中提到的错误。 - irfanmcsd
显示剩余2条评论

0

Cast<type>() 方法不知道如何将您创建的动态对象转换为指定的类型,因此您必须手动执行转换:

using (var entities = new vskdbEntities())
{
     entity.DataFields = "id, stack_trace";
     _list = entities.vsk_error_log
           .OrderBy(entity.Order)
           .Select("New(" + entity.DataFields + ")")
           .Skip(entity.PageSize * entity.PageNumber)
           .Take(entity.PageSize)
           .Select(x => new vsk_error_log 
           {
               Property1 = x.Property1,
               Property2 = x.Property2,
               //etc...
           })
           .ToList();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接