190 votes

Impossible de créer une valeur constante de type Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte.

J'obtiens cette erreur pour la requête ci-dessous

Impossible de créer une valeur constante de type API.Models.PersonProtocol . Seuls les types primitifs ou les types d'énumération sont pris en charge dans ce contexte

ppCombined ci-dessous est un IEnumerable objet de PersonProtocolType qui est construit par la concaténation de 2 PersonProtocol listes.

Pourquoi cet échec ? Ne pouvons-nous pas utiliser LINQ JOIN à l'intérieur de la clause SELECT d'un JOIN ?

var persons = db.Favorites
    .Where(x => x.userId == userId)
    .Join(db.Person, x => x.personId, y => y.personId, (x, y) =>
        new PersonDTO
        {
            personId = y.personId,
            addressId = y.addressId,                   
            favoriteId = x.favoriteId,
            personProtocol = (ICollection<PersonProtocol>) ppCombined
                .Where(a => a.personId == x.personId)
                .Select( b => new PersonProtocol()
                 {
                     personProtocolId = b.personProtocolId,
                     activateDt = b.activateDt,
                     personId = b.personId
                 })
        });

272voto

Slauma Points 76561

Cela ne peut pas fonctionner parce que ppCombined est une collection d'objets en mémoire et vous ne pouvez pas joindre un ensemble de données dans la base de données à un autre ensemble de données en mémoire. Vous pouvez essayer d'extraire les éléments filtrés personProtocol de la ppCombined collection en mémoire après vous avez récupéré les autres propriétés dans la base de données :

var persons = db.Favorites
    .Where(f => f.userId == userId)
    .Join(db.Person, f => f.personId, p => p.personId, (f, p) =>
        new // anonymous object
        {
            personId = p.personId,
            addressId = p.addressId,   
            favoriteId = f.favoriteId,
        })
    .AsEnumerable() // database query ends here, the rest is a query in memory
    .Select(x =>
        new PersonDTO
        {
            personId = x.personId,
            addressId = x.addressId,   
            favoriteId = x.favoriteId,
            personProtocol = ppCombined
                .Where(p => p.personId == x.personId)
                .Select(p => new PersonProtocol
                {
                    personProtocolId = p.personProtocolId,
                    activateDt = p.activateDt,
                    personId = p.personId
                })
                .ToList()
        });

4voto

Versatile Points 396

Dans mon cas, j'ai pu résoudre le problème en procédant comme suit :

J'ai modifié mon code à partir de celui-ci :

var r2 = db.Instances.Where(x => x.Player1 == inputViewModel.InstanceList.FirstOrDefault().Player2 && x.Player2 == inputViewModel.InstanceList.FirstOrDefault().Player1).ToList();

A cela :

var p1 = inputViewModel.InstanceList.FirstOrDefault().Player1;
var p2 = inputViewModel.InstanceList.FirstOrDefault().Player2;
var r1 = db.Instances.Where(x => x.Player1 == p1 && x.Player2 == p2).ToList();

2voto

ebrahim.mr Points 540

J'ai eu ce problème et ce que j'ai fait et résolu le problème est que j'ai utilisé AsEnumerable() juste avant ma clause de jonction. Voici ma requête :

List<AccountViewModel> selectedAccounts;

 using (ctx = SmallContext.GetInstance()) {
                var data = ctx.Transactions.
                    Include(x => x.Source).
                    Include(x => x.Relation).
                    AsEnumerable().
                    Join(selectedAccounts, x => x.Source.Id, y => y.Id, (x, y) => x).
                    GroupBy(x => new { Id = x.Relation.Id, Name = x.Relation.Name }).
                    ToList();
            }

Je me demandais pourquoi ce problème se produisait, et je pense maintenant que c'est parce qu'après avoir effectué une requête via LINQ le résultat sera en mémoire et ne sera pas chargé dans les objets, Je ne sais pas ce qu'est cet état mais ils sont dans certains état transitoire Je pense que Ensuite, lorsque vous utilisez AsEnumerable() o ToList() etc., vous les placez dans des objets de mémoire physique et le problème est résolu.

2voto

Roelant Points 65

Je ne sais pas si quelqu'un fait des recherches à ce sujet. J'ai eu le même problème. Une sélection sur la requête, puis un where (ou une jointure) et l'utilisation de la variable select ont résolu le problème pour moi. (pour moi, le problème se situait dans la collection "Reintegraties")

query.Select(zv => new
            {
                zv,
                rId = zv.this.Reintegraties.FirstOrDefault().Id
            })
            .Where(x => !db.Taken.Any(t => t.HoortBijEntiteitId == x.rId
                                             && t.HoortBijEntiteitType == EntiteitType.Reintegratie
                                             && t.Type == TaakType))
            .Select(x => x.zv);

J'espère que cela aidera quelqu'un.

1voto

James Perih Points 108

Cela vaut la peine d'ajouter, puisque l'exemple de code de l'OP ne fournit pas assez de contexte pour prouver le contraire, mais j'ai également reçu cette erreur avec le code suivant :

public RetailSale GetByRefersToRetailSaleId(Int32 refersToRetailSaleId)
{
    return GetQueryable()
        .FirstOrDefault(x => x.RefersToRetailSaleId.Equals(refersToRetailSaleId));
}

Apparemment, je ne peux pas utiliser Int32.Equals dans ce contexte pour comparer un Int32 avec un int primitif ; j'ai dû (en toute sécurité) passer à cela :

public RetailSale GetByRefersToRetailSaleId(Int32 refersToRetailSaleId)
{
    return GetQueryable()
      .FirstOrDefault(x => x.RefersToRetailSaleId == refersToRetailSaleId);
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X