7

編集:テストに基づいて問題の説明を更新-2011年9月12日。

.ToList()を呼び出すたびに、NotSupportedException( "指定されたメソッドはサポートされていません。")をスローするこのクエリがあります。

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モデル

Dbモデル2

これは、MySQL Connector / NET6.3.4のデータベースストアとしてMySQL5.1(明らかにInnoDBテーブル)を使用しています。

だから私の質問は:なぜこれが機能しないのですか?

注:このリンクのように関連するエンティティを明示的にロードすると、動作させることができます。しかし、EFが私のデータモデルを嫌う理由を知りたいです。

回答:MySQLコネクタは、2番目のネストされたエンティティインクルードを処理できないようです。.NET EFではなく、NotSupportedExceptionをスローします。EF4.0を使用してこれを試したときにも同じエラーが発生しましたが、当時の調査では、問題の原因は自己追跡エンティティであると確信していました。最新のコネクタにアップグレードしようとしましたが、非同期エラーが発生し始めました。これは、私がMySQLを嫌うもう1つの理由です。

4

2 に答える 2

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

私の理解では、これは基本的にあなたのモデルとあなたが試みているクエリを表しています(あなたの質問へのコメントも考慮してください)。ただし、質問のコード スニペットには表示されず、モデルが機能しない重要な違いがどこかにあるはずです。

編集

MySQL コネクタではなく、MS SQL プロバイダー (SQL Server 2008 R2 Express DB) を使用して、上記の動作するコンソール アプリケーションをテストしました。どうやらこれが「重要な違い」だったようです。

于 2011-09-12T20:59:37.950 に答える