[编辑:我在下面留下了原来的问题,有一些更多的上下文和代码来重现问题。下面的简短版本包含问题的本质]
简短版本:下面的查询抛出System.NotSupportedException:“无法强制转换类型'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable
1'.LINQ to Entities仅支持转换实体数据模型基元类型。”仅在VB.Net版本中引发异常。当转换为C#时,不会引发任何异常。
Dim doesThisCrash = From outerOrder In orders
Where outerOrder.ProductId =
(From p In products Join o In orders On p.Id Equals o.ProductId
Order By p.Id
Select p.Id).FirstOrDefault()
Select outerOrder
doesThisCrash.ToList()
因此,为了使其崩溃,似乎我们需要一个子查询,其中原始ObjectSet(订单)与另一个ObjectSet(产品)连接,并且有序。仅使用订单或设置的产品时,不会发生崩溃。当省略Order By时,也没有崩溃。
我倾向于认为这是一个(VB.Net)编译器错误,除非有一些明显的东西我在这里忽略......
现在我的问题仍然存在:
[/编辑]
可选,更长版本(原始问题):
我的域名看起来非常不同,但我将问题转换为更简单的版本,包含以下实体(注意:我实际上使用.edmx设计器定义了这些,因此这是一个简化版本):
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime DateCreated { get; set; }
}
public class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public int ProductId { get; set; }
public DateTime OrderDate { get; set; }
}
public class Customer
{
public int Id { get; set; }
}
我正在尝试在VB.Net中找出一个linq-to-entities查询,它应该在结构上看起来像这样:
Dim db = New SampleEntities()
Dim orders As IQueryable(Of Order) = db.Orders
Dim products As IQueryable(Of Product) = db.Products
Dim currentDate = DateTime.Now
Dim qLinq = From outerOrder In orders
Where outerOrder.OrderDate = currentDate AndAlso
outerOrder.ProductId =
(From p In products Join o In orders On p.Id Equals o.ProductId
Where o.OrderDate = outerOrder.OrderDate AndAlso
outerOrder.CustomerId = o.CustomerId
Order By p.DateCreated
Select p.Id).FirstOrDefault()
Select outerOrder
这会引发System.NotSupportedException:
“无法转换类型'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable
1'.LINQ to Entities仅支持转换实体数据模型基元类型。”
当省略'Order By'部分时,不会引发任何例外。
我真的没有看到为什么不支持这个查询的原因...所以我决定在C#中尝试相同的事情:
var qLinq = from oOut in orders
where oOut.OrderDate == currentDate
&& oOut.ProductId ==
(from p in products join o in orders on p.Id equals o.ProductId
where oOut.OrderDate == o.OrderDate
&& oOut.CustomerId == o.CustomerId
orderby p.DateCreated
select p.Id).FirstOrDefault()
select oOut;
令我惊讶的是,这有效!然后我将C#查询转换为扩展方法语法,然后转回VB,但得到了相同的结果(C#版本工作,VB.Net版本引发了相同的异常)。
所以我猜我的问题是双重的:
供参考,以下是扩展方法语法中的查询:
C#版本:
var q = orders.Where(outerOrder =>
outerOrder.OrderDate == currentDate &&
outerOrder.ProductId ==
(products
.Join(orders,
f => f.Id,
o => o.ProductId,
(f, o) => new { f, o })
.Where(t => t.o.OrderDate == outerOrder.OrderDate
&& outerOrder.CustomerId == t.o.CustomerId)
.OrderByDescending(t => t.f.DateCreated)
.Select(t => t.f.Id))
.FirstOrDefault());
VB.Net版本:
Dim q = orders.Where(Function(outerOrder) outerOrder.OrderDate = currentDate AndAlso
outerOrder.ProductId = (products.Join(orders,
Function(p) p.Id,
Function(o) o.ProductId,
Function(p, o) New With {.p = p, .o = o}).
Where(Function(x) x.o.OrderDate = outerOrder.OrderDate AndAlso
outerOrder.CustomerId = x.o.CustomerId).
OrderByDescending(Function(x) x.p.DateCreated).
Select(Function(x) x.p.Id).
FirstOrDefault()))
答案 0 :(得分:2)
我认为以下工作,但SQL很难看:
Dim qLinq = From outerOrder In orders
Where outerOrder.OrderDate = currentDate AndAlso
outerOrder.ProductId =
(From x In (From p In products
Join o In orders On p.Id Equals o.ProductId
Where o.OrderDate = outerOrder.OrderDate AndAlso
outerOrder.CustomerId = o.CustomerId
Select p.Id)
Order By x).FirstOrDefault()
Select outerOrder
答案 1 :(得分:2)
这有用吗?
Dim a = From p In products Join o In orders On p.Id Equals o.ProductId
Order By p.DateCreated
Select New With {.id = p.Id, .OrderDate = o.OrderDate, .CustomerId = o.CustomerId, .DateCreated = p.DateCreated}
Dim b = From outerOrder In orders _
Where outerOrder.OrderDate = currentDate _
AndAlso outerOrder.ProductId = _
(From x In a Where x.OrderDate = outerOrder.OrderDate _
AndAlso x.CustomerId = outerOrder.CustomerId _
Select x.id).FirstOrDefault
答案 2 :(得分:1)
根据我编辑的答案移动Order By p.DateCreated
行允许查询在没有任何异常的情况下运行。但是,发出的SQL是不同的,所以我认为你没有得到正确的结果。
Dim qLinq = From outerOrder In orders
Let id = (From p In products
Order By p.DateCreated
Join o In orders On p.Id Equals o.ProductId
Where o.OrderDate = outerOrder.OrderDate AndAlso
outerOrder.CustomerId = o.CustomerId
Select p.Id).FirstOrDefault()
Where outerOrder.OrderDate = currentDate AndAlso
outerOrder.ProductId = id
Select outerOrder
答案 3 :(得分:-4)
喜 这可以很容易地工作......
而不是IQueryable
Dim orders As IQueryable(Of Order) = db.Orders
使用列表
Dim orders as List(of Order) = db.Orders.ToList()