2012-03-01 68 views
5

Estoy utilizando el Entity Framework 4.3, POCO, la base de datos primero y yo estoy recibiendo el siguiente error:Cómo evitar "Error interno del proveedor de datos de .NET Framework 1025."?

error del proveedor de datos interna .NET 1025. Marco

PREGUNTA: Creo que mi consulta expresa mi intención, pero parece que estoy alcanzando este error, entonces me pregunto si alguien sabe cómo podría estructurar mi consulta de manera diferente para evitar este error.

Aquí está el panorama ...

que tienen una base de datos de SQL Server 2008 que tiene 2 mesas - A y B:

Un

  • ayuda (int - no null - identity - clave principal)
  • AName (nvarchar (10) - not null)

B

  • Oferta (int - no null - identidad - clave primaria)
  • somename (nvarchar (10) - no nulo)
  • ayuda (int - no null - clave externa de conexión para ayudar en la tabla a)

entonces definir el contexto de esta manera:

public class DatabaseContext : DbContext 
{ 
    public DatabaseContext(string name) 
     : base(name) 
    { 
     Configuration.AutoDetectChangesEnabled = false; 
     As = Set<A>(); 
     Bs = Set<B>(); 
    } 

    public DbSet<A> As { get; private set; } 
    public DbSet<B> Bs { get; private set; } 
} 

y las clases de entidad de este modo:

public class A 
{ 
    public int AId { get; set; } 
    public string AName { get; set; } 
    public virtual ICollection<B> Bs { get; private set; } 

    public void AddB(B b) 
    { 
     if (b == null) 
     { 
      throw new ArgumentNullException("b"); 
     } 

     if (Bs == null) 
     { 
      Bs = new List<B>(); 
     } 

     if (!Bs.Contains(b)) 
     { 
      Bs.Add(b); 
     } 

     b.A = this; 
    } 
} 

public class B 
{ 
    public int BId { get; set; } 
    public A A { get; set; } 
    public string SomeName { get; set; } 
} 

Ahora para la consulta ...

Lo que quiero es toda la medida en que cada "B somename" está en la lista de nombres suministrada por lo hago esto:

var names = new[] {"Name1", "Name2"}; 

var ctx = new DatabaseContext("EFPlayingEntities"); 
var res = ctx.As.Where(a => a.Bs.Select(b => b.SomeName).All(names.Contains)); 

// Here I evaluate the query and I get: 
// Internal .NET Framework Data Provider error 1025. 
Console.WriteLine(res.Count()); 

ser claro acerca de lo que quiero decir, si los datos de la tabla es el siguiente:

AId,AName 
1,A1 
2,A2 
3,A3 
4,A4 

BId,SomeName,AId 
1,Name1,1 
2,Name2,1 
3,Name1,2 
4,Name1,3 
5,Name3,3 
6,Name1,4 
7,Name2,4 

Esperaría recuperar A1, A2 y A4 (de modo que la llamada al recuento anterior devolvería 3).

+0

¿Has mirado en la excepción interna? –

+0

La excepción interna es nulo :-( – kmp

+0

names.Contains no es un código válido, no estoy seguro de cómo se compila. Sospecho que quiere utilizar Intersect() en lugar de All(). –

Respuesta

8

La razón por la que esto sucede es sutil.

Queryable.All necesitan ser llamados con un Expression. Al pasar solo el método 'referencia' crea un delegado, y posteriormente, Enumerable.All se convierte en el candidato en lugar del Queryable.All previsto.

Es por eso que su solución que publicó como respuesta funciona correctamente.

EDITAR

por lo que si se escribe la declaración como esta, que funcionará sin excepción:

var res = ctx.As.Where(
    a => a.Bs.Select(b => b.SomeName).All(b => names.Contains(b))); 
+0

Woah! Así que aunque. Todos (b => nombres.Contiene (b)) es funcionalmente (me refiero en términos de lo que hace, no cómo lo hace) equivalente a. Todos (nombres.Contiene) lo que está diciendo es el subyacente mecanismo es diferente y me encuentro con un error en el EF cuando está evaluando el árbol de expresión? Acabo de probarlo y este "ctx.As.Where (a => a.Bs.Select (b => b.SomeName) .All (b => names.Contains (b)))" de hecho se ejecuta sin error ! ¡Gracias! – kmp

+0

Espero que no te importe, agregué un poco a tu respuesta para que si alguien más se encuentra con esto verán de inmediato el cambio que sugieres. – kmp

+0

@ user1039947: No hay problema :) Esto no es un error de EF, sino una característica que falta con el compilador de expresiones de C#. – leppie

2

He encontrado una solución a esto, en caso de que alguien esté interesado. Hacer lo siguiente es equivalente y no da lugar a la excepción de la pregunta:

var res = ctx 
    .Bs 
    .GroupBy(b => b.A) 
    .Where(g => g.All(b => names.Contains(b.SomeName))) 
    .Select(g => g.Key); 

No sé si esta es la mejor manera de que !?

1

La semántica de su consulta se ve bien para mí; claramente, ¡obtener un error interno del proveedor no es el comportamiento previsto! Hubiera esperado algún mensaje más explícito acerca de que EF no podía traducir tu consulta a una operación de la tienda, si ese es, de hecho, cuál es el problema.

Otra forma de hacer lo que quiera sería:

var names = new[] {"Name1", "Name2"}; 
var nameCount = names.Length; 

var ctx = new DatabaseContext("EFPlayingEntities"); 
var result = ctx.As 
    .Where(a => a.Bs 
       .Select(b => b.SomeName) 
       .Intersect(names) 
       .Count() == a.Bs.Count()); 

(Obtenga cada A tal que se cruzan los nombres de sus B s'con la lista fija da todos los B s)

aunque no he Intenté esto para ver si EF puede traducir este con éxito.

Otra forma:

var names = new[] {"Name1", "Name2"}; 

var ctx = new DatabaseContext("EFPlayingEntities"); 
var result = ctx.As 
    .Where(a => !a.Bs.Select(b => b.SomeName).Except(names).Any()); 

(conseguir cada A tales que la lista de los nombres de sus B s'se reduce a la nada mediante la suscripción de la lista fija)

también probado.

+0

Gracias por la respuesta y ambos ejecutan bien sin excepción. Sin embargo, ninguna de sus soluciones coincide con la funcionalidad que necesito para devolver también una A que tiene una colección de Bs con un subconjunto de la colección de nombres que paso. En mi ejemplo de datos, esperaría que A2 también sea devuelto, ya que tiene "Name1" dentro. – kmp

+0

@user oops, tenía el subconjunto al revés; actualicé mi respuesta. Creo que el modo 'Except' definitivamente es el mejor de los dos ahora. Y sí, todo: su original, su respuesta y mis dos formas, todas tienen la misma semántica, que elegir es puramente una cuestión de gusto y, por supuesto, si EF puede traducir con éxito ... – AakashM

Cuestiones relacionadas