2014-04-12 116 views
1

所以,我一直坚持几个小时试图在我的模型中包含两个嵌套集合的WebAPI。经过数小时的试验和错误,搜索,阅读和更多的试验和错误,我仍然无法弄清楚如何正确地做到这一点。EF6 LINQ嵌套包括

我使用MySQL作为数据库。

我的模型关系是这样的:

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

该模型是建立通过EF代码优先和它的工作数据库,导航关系的工作,以及。

我试图完成的是获取一个帐户,它的字符,每个字符应包括他们的公司和公司的钱包和税。

下工作,并获取所需要的一切,除了税:

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

然而,当我想包括它抛出一个异常,并且不继续税:

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(); 

它失败但有以下例外:

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

内部例外:

<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> 

让我知道是否有任何更多的信息,我可以提供。

在此先感谢您的帮助。

编辑1:

下面给出了同样的异常和错误:

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() 
+0

不获取所有我想要的它对MSSQL工作?不知道MySql,但在Oracle中,如果存在两个以上的嵌套EXISTS,则会得到此异常,因为oracle会从scoop中释放外部表。也许尝试一下MSSQL并查看生成的sql。 – user3411327

回答

1

使用下面

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

由于税收和钱包都在同一个导航属性,所以你不要” t需要包括Agian

然后你可以从C haracter模型

+0

感谢您的回复,这个陈述的问题是,虽然它加载字符和他们的公司,它不加载公司的税收和钱包。 – SorenA

+1

是税收和钱包是导航属性? –

+0

Taxes and Wallets包含一个公司ID作为外键,公司拥有一个列表,该列表通过has-many/with required在模型创建中通过模型构建器映射。 – SorenA

2

正如Janina在评论中指出的,我的导航属性混乱了一点。

我用

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

,而不是

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

在我的模型层固定所有的导航集合属性后,我能够通过

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

不错,你发现你的问题,并自己解决它 –

+0

感谢您的帮助,如果你没有指出它,不会注意到它。 – SorenA