Le type apparaît dans les deux structurellement incompatible initialisations au sein d'une seule requête LINQ to entities

Je suis en train de construire quelque chose comme conditionnelle des requêtes pour obtenir uniquement les données nécessaires à partir de la base de données.

Actuellement, j'ai la requête suivante (qui fonctionne correctement)

var eventData = dbContext.Event.Select(t => new
    {
        Address = true ? new AnonymousEventGetAddress
        {
            AddressLine1 = t.Address.AddressLine1,
            CityName = t.Address.AddressCityName
        } : new AnonymousEventGetAddress(),
    });

Si je l'ai changer pour

var includeAddress = true; //this will normally be passed as param

var eventData = dbContext.Event.Select(t => new
    {
        Address = includeAddress ? new AnonymousEventGetAddress
        {
            AddressLine1 = t.Address.AddressLine1,
            CityName = t.Address.AddressCityName
        } : new AnonymousEventGetAddress(),
    });

J'obtiens l'erreur suivante:

Type "AnonymousEventGetAddress" apparaît dans deux structurellement incompatible initialisations au sein d'une seule requête LINQ to entities.
Un type peut être initialisé à deux endroits dans la même requête, mais seulement si les mêmes propriétés sont définies dans les deux endroits, et ces propriétés sont définies dans le même ordre.

Ce que je fais mal ici (avec le true ça fonctionne) et comment cela peut-il être fixé?

Je sais que la modification de la else-partie à

new AnonymousEventGetAddress
{
    AddressLine1 = null,
    CityName = null
}

fonctionne. Mais si je change l'ordre des propriétés ensuite, cela échouera également.

La classe utilisée est définie suivantes:

public class AnonymousEventGetAddress : BaseAnonymousObject<AnonymousEventGetAddress>
{
    public string AddressLine1 { get; set; }
    public string CityName { get; set; }
}

alors que BaseAnonymousObject<AnonymousEventGetAddress> est défini:

public abstract class BaseAnonymousObject<TAnonymous>
    where TAnonymous : BaseAnonymousObject<TAnonymous>
{
    //this is used in case I have to return a list instead of a single anonymous object
    public static Expression<Func<IEnumerable<TAnonymous>>> Empty => () => new TAnonymous[]{}.AsEnumerable();
}
Je voudrais vous suggérer de ne pas faire d'initialisation de la requête, laisser la requête pour obtenir ce que vous avez besoin, puis jeté que l'anonyme de type à quelque chose (DTO), puis passez par l'initialisation du tout. Souvenir vous travaillez avec IQueryable donc Expression de Func si ces seront compilées à LINQ, ils ne sont pas exécutés...
Je sais que lors de l'exécution des données est nécessaire. Donc, je cherchais un moyen de ne sélectionner que ce qui est vraiment nécessaire, également à partir de la base de données pour conserver les performances de bon. D'autre part j'utilise LINQKit pour permettre l'utilisation de Expression<> qui fonctionnent très bien lors du passage de true.
Créer deux Select expressions, donc vous le faites si includeAddress ou choisir une autre si c'est le contraire. N'essayez pas et composé dans l'expression qu'elle va se faire traiter comme une expression...
C'était juste un exemple simplifié. En cas j'ai les trois en option include... ce serait la fin dans 8 requêtes différentes pour chaque combinaison d'entre eux... Donc je suis encore à se demander quelle est la différence entre la réussite includeAdress (échoue) et true (de travail).

OriginalL'auteur KingKerosin | 2016-08-25