为什么不能将 LINQ to XML 与 LINQ to SQL 结合起来
本文关键字:LINQ to SQL 结合 起来 XML 不能 为什么 | 更新日期: 2023-09-27 18:31:56
我有这段代码:
var xml = XDocument.Load(filePath);
var taxReturns = (from t in xml.Descendants("aangiftes").Elements()
where t.Name == "ib"
select new Domain.TaxReturn
{
FiscalNumber = t.Attribute("sofinr").Value,
Guid = Guid.Parse(t.Attribute("guid").Value),
LastFormOpen = t.Attribute("lastformview").Value,
Name = string.Empty,
TaxYear = t.GetAttributeValue<short>("belastingjaar"),
TaxForm = unitOfWork.TaxForms.FirstOrDefault(tf => tf.Code == t.Attribute("biljetsoort").Value),
}).ToArray();
当我运行此代码时,我收到以下异常:
LINQ to Entities 无法识别方法 System.Xml.Linq.XAttribute Attribute(System.Xml.Linq.XName)-method,并且此方法无法转换为存储表达式
但是,当我将此行提取到方法中时,它工作正常。
有人可以解释这种行为吗?我不明白这种行为:/
这是因为 LINQ 尝试将Domain.TaxReturn {...}
中的代码编译为 SQL。SQL 中没有相应的 API 用于XElement.Attribute(...)
因此会失败。
尝试将XElement
依赖代码移出Domain.TaxReturn {...}
喜欢这个:
var xml = XDocument.Load(filePath);
var taxReturns = (from t in xml.Descendants("aangiftes").Elements()
where t.Name == "ib"
let sofinr = t.Attribute("sofinr").Value
let guid = Guid.Parse(t.Attribute("guid").Value)
let lastformview = t.Attribute("lastformview").Value
let belastingjaar = t.GetAttributeValue<short>("belastingjaar")
let biljetsoort = t.Attribute("biljetsoort").Value
select new Domain.TaxReturn
{
FiscalNumber = sofinr ,
Guid = guid,
LastFormOpen = lastformview,
Name = string.Empty,
TaxYear = belastingjaar,
TaxForm = unitOfWork.TaxForms.Single(tf => tf.Code == biljetsoort),
}).ToArray();
(未经测试)
另外,您可能想使用Enumerable.Single
而不是Enumerable.FirstOrDefault
,或者null
是一个有效的案例?
正如文档中所说 -
当应用程序运行时,LINQ to SQL 会将对象模型中的语言集成查询转换为 SQL,并将其发送到数据库执行
http://msdn.microsoft.com/en-us/library/bb386976%28v=vs.110%29.aspx
仔细检查执行顺序,"先生成 SQL 后执行"
你可以很容易地理解为什么会发生这种情况。在 SQL 中没有替代System.Xml.Linq.XAttribute Attribute(System.Xml.Linq.XName)
。
例如,.OrderBy()
具有 SQL 等效order by
,因此当 LINQ 看到此方法时,它会将其转换为 order by
并执行查询。但是当 linq 看到 System.Xml.Linq.XAttribute Attribute(System.Xml.Linq.XName)
时,没有 SQL 等效项,LINQ 抛出一个错误,说它无法识别它。
但是,当您将该行提取到方法中时,将首先执行该方法,因此此时 LINQ to SQL 已经工作了,并且您要查找的所有实体都已包含在 RAM 中,现在您可以执行任何 LINQ to XML。这次查询不会转换为 SQL,因为实体已经作为托管对象在 RAM 中,并且您的代码工作正常。