LINQ a la entidad: utilizando Contiene en el & # 8220; seleccione & # 8221; parte lanza un error inesperado

StackOverflow https://stackoverflow.com/questions/802159

Pregunta

Tengo una consulta LINQ que va en contra de un objeto Entity Framework. Aquí hay un resumen de la consulta:

//a list of my allies
List<int> allianceMembers = new List<int>() { 1,5,10 };

//query for fleets in my area, including any allies (and mark them as such)
var fleets = from af in FleetSource
             select new Fleet 
             {
                 fleetID = af.fleetID,
                 fleetName = af.fleetName,
                 isAllied = (allianceMembers.Contains(af.userID) ? true : false)
             };

Básicamente, lo que estoy haciendo es conseguir un conjunto de flotas. La lista de allianceMembers contiene INT de todos los usuarios que están aliados conmigo. Quiero establecer isAllied = true si el propietario de la flota forma parte de esa lista, y false en caso contrario.

Cuando hago esto, veo una excepción: " LINQ to Entities no reconoce el método 'Boolean Contains (Int32)' method "

Puedo entender que se produzca este error si hubiera utilizado los contenidos en la parte de dónde de la consulta, pero ¿por qué lo obtendría en la selección? En este punto, asumiría que la consulta se habría ejecutado y devuelto los resultados. Este pequeño código no hace nada para restringir mis datos.

¿Alguna sugerencia sobre cómo puedo lograr lo que necesito al configurar la marca isAllied?

Gracias

¿Fue útil?

Solución

var fleets = from af in FleetSource;

var x = from u in fleets.ToList()
                         select new Fleet
                         {
                            fleetID = u.fleetID,
                            fleetName = u.fleetName,
                            isAllied = (allianceMembers.Contains(u.userID) ? true : false)
                         }

llamando a ToList () en las flotas en las que se ejecuta la consulta, más tarde puede usar Contains () .

Otros consejos

Esto se esconde de una respuesta anterior ...

Contiene no soportado.

IN y JOIN no son el mismo operador (el filtrado por IN nunca cambia la cardinalidad de la consulta).

En lugar de hacerlo de esa manera, usa el método de unión. Es algo difícil de entender sin usar los operadores de consulta, pero una vez que lo obtienes, lo tienes.

var foo = 
model.entitySet.Join(  //Start the join
values, //Join to the list of strings
e => e.Name, // on entity.Name
value => value, //equal to the string
(ModelItem ent, String str) => ent);//select the entity

Aquí está utilizando los operadores de consulta

var foo = from e in model.entitySet
join val in values on
e.Name equals val
select e;

Básicamente, el marco de la entidad intenta traducir su consulta LINQ a una declaración SQL pero no sabe cómo manejar el Contiene .

Lo que puedes hacer en su lugar es recuperar tus flotas de la base de datos y establecer la propiedad isAllied más tarde:

var fleets = (from af in FleetSource
              select new Fleet 
              {
                  fleetID = af.fleetID,
                  fleetName = af.fleetName,
                  userId = af.userId
              }).AsEnumerable();

foreach (var fleet in fleets)
{
    fleet.isAllied = (allianceMembers.Contains(fleet.userID) ? true : false);
}

¡Todos los que están encima de mí están equivocados! (No se ofenda ...) No funciona porque está utilizando la sobrecarga IList de " Contiene " y no la sobrecarga de IEnumerable de " Contiene " ;. Simplemente cambia a:

allianceMembers.Contains<int>(af.userID)

Al agregar < int > , le está diciendo al compilador que use la sobrecarga de IEnumerable en lugar de la sobrecarga de IList.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top