[EDITADO: Dejé la pregunta original a continuación, con algo más de contexto y código para reproducir el problema. La versión corta siguiente contiene la esencia de la cuestión]EF4: La consulta de Entidades LINQ 2 funciona en C# pero no en VB
versión corta: la consulta a continuación lanza una System.NotSupportedException: "No se puede convertir el tipo 'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable
1' LINQ a Entidades sólo admite fundición Entidad. Modelo de datos de tipos primitivos ". La excepción solo se plantea en la versión de VB.Net. Cuando se traduce a C#, no se genera ninguna excepción.
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()
lo tanto, para hacer que se cierre, parece que necesitamos una sub consulta donde el ObjectSet originales (órdenes) se une con otro ObjectSet (productos), y ordenó. Al usar solo los pedidos o los productos configurados, no se produce un bloqueo. Al omitir el Order By, tampoco se produce un bloqueo.
Me inclino a pensar que esto es un (VB.Net) error del compilador, a menos que haya algo obvio que estoy pasando por alto aquí ...
Por ahora mi pregunta sigue en pie:
- ¿por qué una misma consulta aparentemente exacta funciona en C# pero no en VB?
- ¿se puede hacer que esta consulta funcione en VB.Net?
[/ EDIT]
opcional, versión más larga (pregunta original):
Mi dominio se ve muy diferente, pero me tradujo el problema a una versión más simple, con las siguientes entidades (nota: de hecho, me definido estas usando el diseñador .edmx, por lo que esta es una versión simplificada):
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; }
}
que estoy tratando de resolver una consulta LINQ a las entidades que deben buscar strucurally como este, en VB.Net :
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
Esto plantea una System.NotSupportedException:
"No se puede convertir el tipo 'System.Linq.IOrderedQueryable 1' to type 'System.Linq.IQueryable
1'. LINQ a Entidades sólo admite fundición modelo de entidad de datos de tipos primitivos."
Al salir de la 'ORDER BY' parte, se plantea no es una excepción.
Realmente no veo una razón por la que esta consulta no sería apoyado ... Así que decidí intentar hacer lo mismo en 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;
para mi sorpresa, esto funciona luego traduje el C# consulta a la sintaxis método de extensión, y luego de vuelta a VB, pero tengo la misma resultados (la versión de C# funciona, la versión de VB.Net plantea la misma excepción).
Así que supongo que mi pregunta es doble:
- ¿Por qué una apariencia exacta misma obra de consulta en C#, pero no en VB?
- ¿se puede hacer que esta consulta funcione en VB.Net?
Para referencia, aquí están las consultas en sintaxis método de extensión:
C# versión:
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 versión:
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()))
es un código que necesita gran recompensa para pasar tiempo en él :) –
Sería bueno para ver la versión VB de SampleEntities – dbasnett
@dbasnett que sólo se utiliza C# para describir el dominio, en realidad, he utilizado la construí -en la característica de generación de código EF. Solo son algunas clases con propiedades. – jeroenh