C# EF4.1多个嵌套实体包含gets NotSupportedException?

C# EF4.1多个嵌套实体包含gets NotSupportedException?,c#,entity-framework-4,mysql-connector,notsupportedexception,C#,Entity Framework 4,Mysql Connector,Notsupportedexception,编辑:根据测试更新问题描述-2011年9月12日。 我有一个查询,每当我调用.ToList()时,它都会抛出一个NotSupportedException(“指定的方法不受支持”) IQueryable查询=db .文件定义 .Include(x=>x.DefinitionChangeLogs) .Include(x=>x.FieldDefinitions.Select(y=>y.DefinitionChangeLogs))//错误 .Include(x=>x.FieldDefinitions。

编辑:根据测试更新问题描述-2011年9月12日。

我有一个查询,每当我调用.ToList()时,它都会抛出一个NotSupportedException(“指定的方法不受支持”)

IQueryable查询=db
.文件定义
.Include(x=>x.DefinitionChangeLogs)
.Include(x=>x.FieldDefinitions.Select(y=>y.DefinitionChangeLogs))//错误
.Include(x=>x.FieldDefinitions。选择(y=>y.FieldValidationTables))//错误
.式中(x=>x.IsActive);
List retval=query.ToList();
如果我注释掉了我注释为“坏”的任何一行,那么查询就会工作。我还尝试在对象模型中包含不同的嵌套实体,效果相同。包括任何2个将导致崩溃。通过嵌套,我指的是导航属性的导航属性。我还尝试使用带有字符串路径的.Include方法:相同的结果

我的表结构如下所示:

这是使用MySQL 5.1(显然是InnoDB表)作为数据库存储,使用MySQL Connector/NET 6.3.4

所以我的问题是:为什么这不起作用?

注意:如果像中那样显式加载相关实体,我可以让它工作。但我想知道为什么EF讨厌我的数据模型


回答:MySQL连接器显然无法处理第二个嵌套实体include。它抛出NotSupportedException,而不是.NET EF。当我尝试使用EF4.0时,同样的错误也存在,但我当时的研究让我相信是自我跟踪实体导致了这个问题。我尝试升级到最新的连接器,但它开始导致错误。这让我讨厌MySQL。

我制作了一个小控制台应用程序来测试您的场景,这个测试应用程序可以工作:

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();
            }
        }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.Data.Entity;
使用System.Linq;
名称空间EFIncludeTest
{
公共类父类
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection ChildLevel1s{get;set;}
}
公共类儿童1级
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共ICollection ChildLevel2as{get;set;}
公共ICollection ChildLevel2bs{get;set;}
}
公营儿童班2A
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公营儿童班2b
{
公共int Id{get;set;}
公共字符串名称{get;set;}
}
公共类MyContext:DbContext
{
公共数据库集父项{get;set;}
}
班级计划
{
静态void Main(字符串[]参数)
{
//创建要测试的实体
使用(var ctx=new MyContext())
{
var parent=新父级
{
Name=“Parent”,
ChildLevel1s=新列表
{
新儿童级别1
{
Name=“FirstChildLevel1”,
ChildLevel2as=新列表
{
新的ChildLevel2a{Name=“FirstChildLevel2a”},
新建ChildLevel2a{Name=“SecondChildLevel2a”}
},
ChildLevel2bs=新列表
{
新的ChildLevel2b{Name=“FirstChildLevel2b”},
新建ChildLevel2b{Name=“SecondChildLevel2b”}
}
},
新儿童级别1
{
Name=“SecondChildLevel1”,
ChildLevel2as=新列表
{
新的ChildLevel2a{Name=“ThirdChildLevel2a”},
新的ChildLevel2a{Name=“ForthChildLevel2a”}
},
ChildLevel2bs=新列表
{
新的ChildLevel2b{Name=“ThirdChildLevel2b”},
新的ChildLevel2b{Name=“ForthChildLevel2b”}
}
},
}
};
ctx.Parents.Add(parent);
ctx.SaveChanges();
}
//在新上下文中检索
使用(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==“父项”)
.ToList();
//没有例外
//签入调试器:已加载所有子级
Console.ReadLine();
}
}
}
}
我的理解是,这基本上代表了您的模型和您正在尝试的查询(还考虑了您对问题的评论)。但是,一定有一个重要的区别,它在您的问题中的代码片段中不可见,并且使您的模型无法工作

编辑


我已经使用MS SQL provider(SQL Server 2008 R2 Express DB)而不是MySQL连接器测试了上面的工作控制台应用程序。显然,这是“重要的区别”。

参加聚会可能有点晚,但我发现以下变通方法在当前项目中相当有用:

IQueryable<FileDefinition> query = db.FileDefinitions
    .Include(x => x.FieldDefinitions.Select(y => y.DefinitionChangeLogs.Select(z => z.FieldDefinition.FieldValidationTables)))
IQueryable query=db.FileDefinitions
.Include(x=>x.FieldDefinitions.Select(y=>y.DefinitionChangeLogs.Select(z=>z.FieldDefinition.FieldValidationTables)))
如果不使用第二行包含,请使用Selec
IQueryable<FileDefinition> query = db.FileDefinitions
    .Include(x => x.FieldDefinitions.Select(y => y.DefinitionChangeLogs.Select(z => z.FieldDefinition.FieldValidationTables)))