然而,在使用Linq-To-Sql时,我遇到了几种情况,它比最新的Entity Framework更强大,我想知道是否有人知道原因?其中大部分似乎与转换有关。例如,以下查询在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正常工作,我必须将
select
移动到First()
调用之后。另一个例子是我的查询来检索客户列表。在查询中,我将其转换为匿名结构以便转换为
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 无法处理比较实体的 where 子句,而 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();
这会抛出一个带有信息DbArithmeticExpression arguments must have a numeric common type.
的ArgumentException
异常。
为什么似乎实体框架中Linq查询的能力比L2S差了?