简体   繁体   中英

EF6 LINQ nested includes

So, I've been stuck for hours trying to include two nested collections in my model for a WebAPI. After hours of trial and error, searching, reading and more trial and error I still cant figure out how to do this properly.

Im using MySQL as database.

My model relationships looks like this:

Account <-1:m-> Character
Character <-m:1-> Corporation
Corporation <-1:m-> CorporationWallet
Corporation <-1:m-> CorporationTaxes

The model is set up through EF Code-First and it's working in the database, the navigation relationships are working as well.

What I'm trying to accomplish is to fetch an account and it's characters, each character should include their corporation and that corporations wallets and taxes.

The following works and fetches everything needed, except the taxes:

Account account = db.Accounts
    .Include(x => x.Characters.Select(y => y.Corporation.Wallets))
    .Where(o => o.AccessToken == accessToken)
    .Take(1)
    .ToList()
    .FirstOrDefault();

However when i wish to include the taxes it throws an exception and doesn't continue:

Account account = db.Accounts
    .Include(x => x.Characters.Select(y => y.Corporation.Wallets))
    .Include(x => x.Characters.Select(y => y.Corporation.Taxes))
    .Where(o => o.AccessToken == accessToken)
    .Take(1)
    .ToList()
    .FirstOrDefault();

It fails with the following exception:

An error occurred while executing the command definition. See the inner exception for details.

Inner exception:

<Message>An error has occurred.</Message>
<ExceptionMessage>Unknown column 'UnionAll1.C1' in 'field list'</ExceptionMessage>
<ExceptionType>MySql.Data.MySqlClient.MySqlException</ExceptionType>
<StackTrace>
at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.Entity.EFMySqlCommand.ExecuteDbDataReader(CommandBehavior behavior)
at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.<Reader>b__c(DbCommand t, DbCommandInterceptionContext`1 c)
at System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch[TTarget,TInterceptionContext,TResult](TTarget target, Func`3 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed)
at System.Data.Entity.Infrastructure.Interception.DbCommandDispatcher.Reader(DbCommand command, DbCommandInterceptionContext interceptionContext)
at System.Data.Entity.Internal.InterceptableDbCommand.ExecuteDbDataReader(CommandBehavior behavior) at System.Data.Common.DbCommand.ExecuteReader(CommandBehavior behavior)
at System.Data.Entity.Core.EntityClient.Internal.EntityCommandDefinition.ExecuteStoreCommands(EntityCommand entityCommand, CommandBehavior behavior)
</StackTrace>

Let me know if there is any more information i can provide.

Thanks in advance for your help.

Edit 1:

The following gives the same exception and error:

var query = from acc in db.Accounts
            where acc.AccessToken == accessToken
            select new
            {
                acc,
                Characters = from cha in acc.Characters
                             select new
                             {
                                 cha,
                                 Account = cha.Account,
                                 Corporation = cha.Corporation,
                                 Taxes = from tax in cha.Corporation.Taxes
                                         select new
                                         {
                                             tax,
                                             Corporation = tax.Corporation
                                         },
                                 Wallets = from wallet in cha.Corporation.Wallets
                                           select new
                                           {
                                               wallet,
                                               Corporation = wallet.Corporation
                                           }
                             }
            };
Account account = query
    .Select(x => x.acc)
    .FirstOrDefault()

As Janina pointed out in a comment, my navigational properties were jumbled a bit.

I was using

[InverseProperty("Corporation")]
public List<CorporationTax> Taxes { get; set; }
[InverseProperty("Corporation")]
public List<CorporationWallet> Wallets { get; set; }

instead of

[InverseProperty("Corporation")]
public virtual ICollection<CorporationTax> Taxes { get; set; }
[InverseProperty("Corporation")]
public virtual ICollection<CorporationWallet> Wallets { get; set; }

After fixing all the navigational collection properties across my model layer i was able to fetch all i wanted through

Account account = db.Accounts
    .Where(o => o.AccessToken == accessToken)
    .Take(1)
    .ToList()
    .FirstOrDefault();

Use below

Account account = db.Accounts
    .Include(x => x.Characters)
    .Where(o => o.AccessToken == accessToken)
    .Take(1)
    .ToList()
    .FirstOrDefault();

Because Taxes and Wallets are in the same Navigation Property so you don't need to Include agian

Then you can get every property from Character Model

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM