实体框架 – 为什么EF 4.1不支持复杂的查询以及linq-to-sql?

前端之家收集整理的这篇文章主要介绍了实体框架 – 为什么EF 4.1不支持复杂的查询以及linq-to-sql?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在将现有数据库中的内部Web应用程序从 Linq-To-sql转换为EF CodeFirst.我最近一直对Linq-To-sql的限制感到恼火,更新一个非常交织在一起的数据库表后,不得不更新edmx,最终使我无法切换到EF.

然而,我遇到几种情况,使用linq与Linq-To-sql比最新的实体框架更强大,我想知道是否有人知道它的推理?大多数似乎是处理转型.例如,以下查询在L2S中工作,但不在EF中:

var client = (from c in _context.Clients
                      where c.id == id
                      select Clientviewmodel.ConvertFromEntity(c)).First();

在L2S中,它可以从数据库中正确地检索客户端并将其转换为Clientviewmodel类型,但是在EF中,这种异常表明Linq to Entities不会识别方法(这在我写的时候是有道理的.

为了让这个工作在EF中,我必须在First()调用之后移动select.

另一个例子是我的查询来检索客户端列表.在我的查询中,我将其转换为匿名结构以转换为JSON:

var clients = (from c in _context.Clients
                       orderby c.name ascending
                       select new
                       {
                           id = c.id,name = c.name,versionString = Utils.GetVersionString(c.ProdVersion),versionName = c.ProdVersion.name,date = c.prod_deploy_date.ToString()
                       })
                       .ToList();

我的Utils.GetVersionString()方法不仅在EF中引起不受支持方法异常,而且c.prod_deploy_date.ToString()也导致一个异常,而且这是一个简单的DateTime.像以前一样,为了修复它,我不得不在ToList()之后做我的选择转换.

编辑:另一个我刚刚遇到的情况是,EF无法处理那些比较实体的子句,如L2S对此没有任何问题.例如查询

context.TfsWorkItemTags.Where(x => x.TfsWorkItem == TfsWorkItemEntity).ToList()

抛出异常,而我必须做

context.TfsWorkItemTags.Where(x => x.TfsWorkItem.id == tfsWorkItemEntity.id).ToList()

编辑2:我想添加另一个我发现的问题.显然你不能在EF Linq查询中使用数组,这可能比任何事情都更糟.所以例如,现在我将一个表示一个版本的实体转换成int [4],并尝试查询它.在Linq-to-sql中我使用以下查询

return context.ReleaseVersions.Where(x => x.major_version == ver[0] && x.minor_version == ver[1]
                                          && x.build_version == ver[2] && x.revision_version == ver[3])
                              .Count() > 0;

这将失败,但出现以下异常:

The LINQ expression node type 'ArrayIndex' is not supported in LINQ to Entities.

编辑3:我发现另一个EF的不良Linq实现实例.以下是在L2S中工作但不在EF 4.1中的查询

DateTime curDate = DateTime.Now.Date;
        var reqs = _context.TestRequests.Where(x => DateTime.Now > (curDate + x.scheduled_time.Value)).ToList();

这会抛出一个ArgumentException,并带有消息DbArithmeticExpression参数必须有数字通用类型.

为什么看起来他们降级了在EF中的Linq查询的能力比L2S?

解决方法

Edit(9/2/2012):更新为反映.NET 4.5,并添加了更多缺少的功能

这不是答案 – 这不可能是因为唯一能够回答您问题的合格人员可能是ADO.NET团队的产品经理.

如果您检查旧数据集的功能集,那么linq-to-sql,然后是EF,您会发现在较新的API中,关键功能删除,因为较新的API在更短的时间内被开发出来,因此能够提供新颖的功能.

只列出DataSet中可用的一些关键功能,但在稍后的API中不可用:

>批处理
>唯一键

在Linq-to-sql中可用的功能,但在EF中不支持(可能列表不完全正确,长时间没有使用L2S):

>记录数据库活动
> Lazy加载属性
>自第一个版本以来的左外连接(DefaultIfEmpty)(从EFv4开始,EF具有它)
>全球渴望加载定义
AssociateWith – 例如加载数据的条件
>第一版以来的代码
> IMultipleResults支持返回多个结果集的存储过程(EF在.NET 4.5中有它,但没有设计师支持功能)
>支持表值函数(EF在.NET 4.5中有此功能)
>还有一些

现在我们可以列出EF ObjectContext API(EFv4)中可用的功能,并且在DbContext API(EFv4.1)中缺少:

>映射存储过程
>条件映射
>映射数据库函数
定义查询,QueryViews,模型定义函数
>除非将DbContext转换回ObjectContext,否则Esql不可用
>独立关系的操作状态是不可能的,除非您将DbContext转换回ObjectContext
>使用MergeOption.OverwriteChanges和MergeOption.PreserveChanges是不可能的,除非您将DbContext转换回ObjectContext
>还有一些

我个人对此的感觉只是很大的悲伤.缺少核心功能删除了以前API中存在的功能,因为ADO.NET团队显然没有足够的资源来重新实现它们 – 这在许多情况下使迁移路径几乎不可能.整个情况更糟,因为缺少功能或迁移障碍并不直接列出(甚至ADO.NET团队甚至不知道他们,直到有人报告他们).

因为我认为DbContext API的全部想法是管理失败.目前,ADO.NET团队必须维护两个API –DbContext并不成熟以替代ObjectContext,它实际上不能因为它只是一个包装器,因为该ObjectContext不能死.可用于EF开发的资源大概减半.

还有更多的问题相关.一旦我们离开ADO.NET团队,从MS产品套件的角度来看这个问题,我们将会看到如此多的差异,我有时甚至怀疑是否有任何全球战略.

简单地说,EF的提供者以不同的方式工作,在Linq-to-sql中工作的查询不必与EF一起工作.

原文链接:https://www.f2er.com/mssql/75140.html

猜你在找的MsSQL相关文章