EF4.1 Несколько вложенных объектов Включает получает NotSupportedException? - PullRequest
6 голосов
/ 10 сентября 2011

Редактировать: обновленное описание проблемы на основе тестирования - 12 сентября 2011 г.

У меня есть этот запрос, который выдает исключение 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 Connector / NET 6.3.4.

Итак, мой вопрос: почему это не работает?

Примечание: я могу заставить его работать, если я явно загружаю связанные объекты, как в этой ссылке .Но я хочу знать, почему EF ненавидит мою модель данных.

ОТВЕТ: MySQL, Connector, по-видимому, не способен обрабатывать 2-е вложенное включение сущности.Выдает исключение NotSupportedException, а не .NET EF.Та же самая ошибка также присутствовала, когда я пытался сделать это, используя EF4.0, но мои исследования в то время привели меня к мысли, что проблема возникла из-за самосопровождения сущностей.Я попытался обновить до последней версии Connector, но он начал вызывать ошибку Out of Sync .Это еще одна причина для меня ненавидеть MySQL.

Ответы [ 2 ]

3 голосов
/ 14 апреля 2014

Может быть, немного опоздал на вечеринку, но я нашел следующий обходной путь довольно полезным в текущем проекте:

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

В тех случаях, когда вместо использования второй строки включений, нажмите «Выбрать», чтобы вернуться к исходному свойству навигации, и еще один «Выбрать», чтобы перейти вперед к свойству, которое необходимо включить.

2 голосов
/ 13 сентября 2011

Я сделал небольшое консольное приложение для проверки вашего сценария, и это тестовое приложение работает:

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 Express DB), а не с MySQL Connector. Видимо, это и было «важным отличием».

...