Pregunta

Recibo un error de tiempo de compilación al compilar el siguiente código y no puedo ver por qué:

Las relaciones son muchas de muchas relaciones

 var contacts = groups_to_querry
                .SelectMany(x => x.Contacts)
                .Where(x => x.ID == Guid.Empty)
                .SelectMany(p => p.ContactDetails)
                .Where(x => x.ID == Guid.Empty)
                .SelectMany(x => x.Contacts);  //This line gives me a compile time error 
                //Error : The Type argumetns for method 'System.Linq.Enumerable.SelectMany<TSource,Tresult>
                //(System.Collections.Generic.IEnumerable<TSource>, System.Func<TSource,
                //System.Collections.Generic.IEnumerable<TResult>>)' cannot be infrred from the usage.  
                //Try specifying the type arguments explicitly
¿Fue útil?

Solución

La segunda vez que llamas .SelectMany(x => x.Contacts), actualmente estás trabajando con una colección de ContactDetails. Es dudoso que puedas usar SelectMany en eso. Necesitarías usar Select en cambio.

SelectMany se usa cuando desea seleccionar múltiples colecciones de elementos y ponerlos en uno IEnumerable. Select se usa en campos individuales. Ya que estás trabajando con objetos de tipo ContactDetail (que supongo que solo puede tener un contacto), necesitaría usar Select

Editar: Esto es lo que estás haciendo en pocas palabras, paso a paso:

groups_to_querry.SelectMany(x => x.Contacts): De todos los grupos que quiero consultar seleccione todos sus contactos. Cada grupo tiene muchos contactos, así que póngalos todos en un solo IEnumerable colección de tipo Contact

.Where(x => x.ID == Guid.Empty): ... pero solo esos contactos con una identificación vacía

.SelectMany(p => p.ContactDetails): Luego seleccione todos esos contactos de CONTACTA CALLAS. Cada contacto tiene muchas colas de contacto, así que póngalos todos en un solo IEnumerable colección de tipo ContactDetail

.Where(x => x.ID == Guid.Empty): ... pero solo esas cortes de contacto con una identificación vacía

.SelectMany(x => x.Contacts);: Ahora seleccione cada uno de los muchos contactos de Contact Details. Sin embargo, dado que el compilador sabe que existe una relación de uno a muchos entre contactos y colas de contacto (y no al revés), esa declaración no es posible, y por lo tanto muestra un error de compilación

Otros consejos

Estoy interpretando su consulta prevista como "De múltiples grupos de contactos, seleccione todos los contactos que tienen ID = Guid.empty y también tienen detalles que todos tienen ID = Guid.empty".

La forma en que se interpreta su código es "de todos los contactos que tienen GUID.Epty, seleccione todos los detalles que tienen Guid.Epty, y de esos detalles seleccione todos los contactos". El primer problema es que termina seleccionando de detalles. Esto significa la final SelectMany debería ser un Select, porque x.Contacts Aquí se refiere a la relación de muchos a uno, desde detalles hasta contactos.

El segundo problema es que el resultado contendrá duplicados de contactos, porque se incluye el mismo contacto para cada detalle. Lo que debería estar haciendo en su lugar es filtrar los contactos directamente en función de sus colecciones de detalles, como esta:

groups_to_query
.SelectMany(g => g.Contacts)
.Where(c => c.ID == Guid.Empty)
.Where(c => c.ContactDetails.All(d => d.ID == Guid.Empty))

Tenga en cuenta que esto también seleccionaría contactos que tienen cero detalles, lo cual es un comportamiento diferente de su consulta, por lo que no estoy seguro de si es lo que desea. Podrías agregar otro filtro para ContactDetails.Any() que no.

Editar: Dado que está utilizando el marco de la entidad, lo anterior probablemente no funcionará. Es posible que deba seleccionar los detalles en una subconsulta y luego filtrar en la memoria después de que se ejecuta:

var queryResult =
    groups_to_query
    .SelectMany(g => g.Contacts)
    .Where(c => c.ID == Guid.Empty)
    .Select(c => new {
        contact = c,
        detailIDs = c.ContactDetails.Select(d => d.ID)
    }).ToList();

var contacts =
    queryResult
    .Where(r => r.detailIDs.All(id => id == Guid.Empty))
    .Select(r => r.contact);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top