6

編輯:根據測試更新問題說明 - 09月12日2011年EF4.1多重嵌套實體包括獲取NotSupportedException?

我有這樣的查詢引發NotSupportedException每當我打電話.ToList()(「不支持指定的方法。」)。

IQueryable<FileDefinition> query = db 
    .FileDefinitions 
    .Include(x => x.DefinitionChangeLogs) 
    .Include(x => x.FieldDefinitions.Select(y => y.DefinitionChangeLogs)) // bad 
    .Include(x => x.FieldDefinitions.Select(y => y.FieldValidationTables)) // bad 
    .Where(x => x.IsActive); 
List<FileDefinition> retval = query.ToList(); 

如果我註釋掉任何一條我已評論爲「不好」的行,那麼查詢就起作用。我也嘗試在我的對象模型中包含不同的嵌套實體,效果相同。包括任何2將導致崩潰。嵌套,我的意思是導航屬性的導航屬性。我也嘗試使用.include方法與字符串路徑:相同的結果。

我的表結構是這樣的:

Db model

Db model 2

這是使用MySQL 5.1(InnoDB表明顯)與MySQL連接/ NET 6.3.4數據庫存儲。

所以我的問題是:爲什麼不工作?

注意:如果我明確加載像this link這樣的相關實體,我可以得到它的工作。但我想知道爲什麼EF討厭我的數據模型。

回答:MySQL Connector顯然不能處理第二個嵌套實體include。它引發NotSupportedException,而不是.NET EF。當我嘗試使用EF4.0時,也出現了同樣的錯誤,但是當時我的研究讓我相信這是導致問題的自我跟蹤實體。我嘗試升級到最新的連接器,但它開始導致Out of Sync error。對我來說這是yet another reason討厭MySQL。

+0

如果僅*離開包含標記爲「壞」的'Include'並刪除另外兩個包含?那它有用嗎? – Slauma

+0

@Slauma是的,第二行自行工作。我做了更多的測試,並且它似乎是導致崩潰的第二個和第三個包含的組合。他們自己工作,但不在一起。 FieldValidationTables集合從數據庫的視圖中加載,我必須在EF模型中手動設置關係。它具有FieldDefinitionId和TableName字段。 FieldDefintion 1 <-> * FieldValidationTable –

+0

我不知道這個問題是什麼。您可能需要在您的問題中添加更多詳細信息才能獲得答案(主要是爲了讓簡單示例模型中的其他人可以重現問題)。 – Slauma

回答

2

我已經做了小控制檯應用程序來測試您的方案和測試應用程序的工作原理:

using System; 
using System.Collections.Generic; 
using System.Data.Entity; 
using System.Linq; 

namespace EFIncludeTest 
{ 
    public class Parent 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public ICollection<ChildLevel1> ChildLevel1s { get; set; } 
    } 

    public class ChildLevel1 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
     public ICollection<ChildLevel2a> ChildLevel2as { get; set; } 
     public ICollection<ChildLevel2b> ChildLevel2bs { get; set; } 
    } 

    public class ChildLevel2a 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    public class ChildLevel2b 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    public class MyContext : DbContext 
    { 
     public DbSet<Parent> Parents { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      // Create entities to test 
      using (var ctx = new MyContext()) 
      { 
       var parent = new Parent 
       { 
        Name = "Parent", 
        ChildLevel1s = new List<ChildLevel1> 
        { 
         new ChildLevel1 
         { 
          Name = "FirstChildLevel1", 
          ChildLevel2as = new List<ChildLevel2a> 
          { 
           new ChildLevel2a { Name = "FirstChildLevel2a" }, 
           new ChildLevel2a { Name = "SecondChildLevel2a" } 
          }, 
          ChildLevel2bs = new List<ChildLevel2b> 
          { 
           new ChildLevel2b { Name = "FirstChildLevel2b" }, 
           new ChildLevel2b { Name = "SecondChildLevel2b" } 
          } 
         }, 

         new ChildLevel1 
         { 
          Name = "SecondChildLevel1", 
          ChildLevel2as = new List<ChildLevel2a> 
          { 
           new ChildLevel2a { Name = "ThirdChildLevel2a" }, 
           new ChildLevel2a { Name = "ForthChildLevel2a" } 
          }, 
          ChildLevel2bs = new List<ChildLevel2b> 
          { 
           new ChildLevel2b { Name = "ThirdChildLevel2b" }, 
           new ChildLevel2b { Name = "ForthChildLevel2b" } 
          } 
         }, 
        } 
       }; 

       ctx.Parents.Add(parent); 
       ctx.SaveChanges(); 
      } 

      // Retrieve in new context 
      using (var ctx = new MyContext()) 
      { 
       var parents = ctx.Parents 
        .Include(p => p.ChildLevel1s.Select(c => c.ChildLevel2as)) 
        .Include(p => p.ChildLevel1s.Select(c => c.ChildLevel2bs)) 
        .Where(p => p.Name == "Parent") 
        .ToList(); 

       // No exception occurs 
       // Check in debugger: all children are loaded 

       Console.ReadLine(); 
      } 
     } 
    } 
} 

我的理解是,這基本上代表了你的模型和你正試圖查詢(也考慮您的意見考慮到你的問題)。但是某處必須是一個重要的區別,它不會在您的問題的代碼片段中看到,並且會導致您的模型無法工作。

編輯

我與MS SQL提供商(SQL Server 2008 R2的快遞DB),而不是MySQL連接測試上面的工作控制檯應用程序。顯然這是「重要的區別」。

+0

對堆棧跟蹤進行更全面的回顧可以看出,它是拋出異常的MySQL連接器軟件。換句話說,MySQL連接器主動不允許這種情況發生,而不是EF4.1。 –

+0

@Kasey:很好,你發現問題的根源!這不是我在這裏看到的EF MySQL連接器的第一個限制。 – Slauma

+0

是的,我遇到了很多MySQL的限制和錯誤。我希望我能及時回到MSSQL開始這個項目。 –

3

也許有點遲到了,但我發現了以下解決方法在當前項目中相當有用:

IQueryable<FileDefinition> query = db.FileDefinitions 
    .Include(x => x.FieldDefinitions.Select(y => y.DefinitionChangeLogs.Select(z => z.FieldDefinition.FieldValidationTables))) 

在哪裏,而不是使用第二排的包括,使用選擇要回原來導航財產和另一個選擇轉到您需要包含的財產。

+0

感謝您的解決方法。我不再參與這個項目,但希望它能幫助其他人。我也避免了最近的ORM。 –