válido solicitado que puede proveedor net instalado framework esté especificado encuentra datos configuración almacenamiento c# .net entity-framework entity-framework-4 expression-trees

c# - solicitado - el proveedor de almacenamiento especificado no se encuentra en la configuración o no es válido



Error interno del proveedor de datos de.NET Framework 1025 (5)

IQueryable<Organization> query = context.Organizations; Func<Reservation, bool> predicate = r => !r.IsDeleted; query.Select(o => new { Reservations = o.Reservations.Where(predicate) }).ToList();

esta consulta arroja la excepción "Error interno del proveedor de datos de .NET Framework 1025", pero la consulta siguiente no.

query.Select(o => new { Reservations = o.Reservations.Where( r => !r.IsDeleted) }).ToList();

Necesito usar el primero porque necesito verificar algunas declaraciones if para construir el predicado correcto. Sé que no puedo usar declaraciones if en esta circunstancia, es por eso que paso un delegado como parámetro.

¿Cómo puedo hacer que la primera consulta funcione?


Acabo de experimentar este problema en un escenario diferente.

Tengo una clase estática llena de predicados de Expression que luego puedo combinar o pasar a una consulta de EF. Uno de ellos fue:

public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus( IEnumerable<EventEnums.AttendeeStatus> statuses) { return ce => ce.Event.AttendeeStatuses .Where(a => a.ClientId == ce.Client.Id) .Select(a => a.Status.Value) .Any(statuses.Contains); }

Esto arrojaba el error 1025 debido a la llamada al grupo del método Contains . El marco de la entidad esperaba una expresión y encontró un grupo de métodos , que dio como resultado el error. Convertir el código para usar un lambda (que se puede convertir implícitamente en una expresión) solucionó el error

public static Expression<Func<ClientEvent, bool>> ClientHasAttendeeStatus( IEnumerable<EventEnums.AttendeeStatus> statuses) { return ce => ce.Event.AttendeeStatuses .Where(a => a.ClientId == ce.Client.Id) .Select(a => a.Status.Value) .Any(x => statuses.Contains(x)); }

Aparte: luego simplifiqué la expresión a ce => ce.Event.AttendeeStatuses.Any(a => a.ClientId == ce.Client.Id && statuses.Contains(a.Status.Value));


Gracias por hacerme un ping. Supongo que estaba en el camino correcto después de todo.

De todos modos, para reiterar, LINQ to Entities (gracias a Jon Skeet por corregirme cuando me confundí en mi propio proceso de pensamiento en los comentarios) opera en Expression Trees ; permite una proyección para traducir la expresión lambda a SQL por QueryProvider .

Regular Func<> funciona bien para LINQ to Objects.

Entonces, en este caso, cuando usa Entity Framework, cualquier predicado que pase a IQueryable de EF tiene que ser Expression<Func<>> .


Si bien las respuestas anteriores son verdaderas, tenga en cuenta que al intentar usarlas después de una instrucción select, debe llamar a AsQueryable() explícitamente; de ​​lo contrario, el compilador asumirá que estamos tratando de usar métodos IEnumerable, que esperan Func y no Expression<Func> .

Este fue probablemente el tema del póster original, ya que de lo contrario el compilador se quejará la mayor parte del tiempo de que está buscando Expression<Func> y no Func .

Demostración: Lo siguiente fallará:

MyContext.MySet.Where(m => m.SubCollection.Select(s => s.SubItem).Any(expr)) .Load()

Mientras que lo siguiente funcionará:

MyContext.MySet.Where(m => m.SubCollection.Select(s => s.SubItem).AsQueryable().Any(expr)) .Load()


Tuve un problema similar. Biblioteca de ViewModels que se ve así:

public class TagViewModel { public int Id { get; set; } public string Name { get; set; } public static Expression<Func<SiteTag, TagViewModel>> Select = t => new TagViewModel { Id = t.Id, Name = t.Name, };

Esto funciona:

var tags = await db.Tags.Take(10).Select(TagViewModel.Select) .ToArrayAsync();

Pero esto no compilará

var post = await db.Posts.Take(10) .Select(p => new { Post = p, Tags = p.Tags.Select(pt => pt.Tag).Select(TagViewModel.Select) }) .ToArrayAsync();

Debido a que el segundo .Select es un desastre, el primero se cancela de una ICollection, que no es IQueryable, por lo que consume esa primera Expression como Func simple, no Expression<Func... Eso devuelve IEnumerable<... , como se explica en esta página. Entonces .AsQueryable() al rescate:

var post = await db.Posts.Take(10) .Select(p => new { Post = p, Tags = p.Tags.Select(pt => pt.Tag).AsQueryable() .Select(TagViewModel.Select) }) .ToArrayAsync();

Pero eso crea un problema nuevo y más extraño: O recibo Internal Framework ... Error 1025, o obtengo la variable post con una propiedad .Post cargada, pero la propiedad .Tags tiene un objeto proxy EF que parece ser usado para Carga lenta.

La solución es controlar el tipo de devolución de Etiquetas, al finalizar el uso de la clase Anónimo:

public class PostViewModel { public Post Post { get; set; } public IEnumerable<TagViewModel> Tags { get; set; }

Ahora selecciona esto y todo funciona:

var post = await db.Posts.Take(10) .Select(p => new PostViewModel { Post = p, Tags = p.Tags.Select(pt => pt.Tag).AsQueryable() .Select(TagViewModel.Select) }) .ToArrayAsync();


Después de crear la recompensa (¡ratas!), Encontré esta respuesta , que resolvió mi problema. (Mi problema involucraba una llamada .Any() , que es un poco más complicada que esta pregunta ...)

En resumen, esta es tu respuesta:

IQueryable<Organization> query = context.Organizations; Expression<Func<Reservation, bool>> expr = r => !r.IsDeleted; query.Select(o => new { Reservations = o.Reservations.Where(expr) }) .ToList();

Lea la respuesta a la que se hace referencia para obtener una explicación de por qué necesita la variable local expr y no puede hacer referencia directamente a otro método del tipo de retorno Expression<Func<Reservation, bool>> .