sql >> Database teknologi >  >> RDS >> Mysql

Hvordan kan jeg bruge Entity Framework på en objektgraf forbi en dybde på 2 med MySQL Connector / NET?

Rediger

Testen nedenfor blev lavet med SQL Server og SqlClient som udbyder. Det faktum, at problemet ikke kan reproduceres med SQL Server rejser spørgsmålet, om MySql udbyder, du bruger, har en fejl i, der skaber forkert SQL til din LINQ-forespørgsel. Det ligner det samme problem som i dette spørgsmål hvor problemet opstod med en MySql udbyder også og kunne ikke gengives med SqlClient /SQL-server.

Jeg har testet eksemplet med fed skrift (med EF 4.3.1) og kan ikke gengive problemet:

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

namespace EFInclude
{
    public class Harbor
    {
        public int HarborId { get; set; }
        public virtual ICollection<Ship> Ships { get; set; }

        public string Description { get; set; }
    }

    public class Ship
    {
        public int ShipId { get; set; }
        public int HarborId { get; set; }
        public virtual Harbor Harbor { get; set; }
        public virtual ICollection<CrewMember> CrewMembers { get; set; }

        public string Description { get; set; }
    }

    public class CrewMember
    {
        public int CrewMemberId { get; set; }
        public int ShipId { get; set; }
        public virtual Ship Ship { get; set; }
        public int RankId { get; set; }
        public virtual Rank Rank { get; set; }
        public int ClearanceId { get; set; }
        public virtual Clearance Clearance { get; set; }

        public string Description { get; set; }
    }

    public class Rank
    {
        public int RankId { get; set; }
        public virtual ICollection<CrewMember> CrewMembers { get; set; }

        public string Description { get; set; }
    }

    public class Clearance
    {
        public int ClearanceId { get; set; }
        public virtual ICollection<CrewMember> CrewMembers { get; set; }

        public string Description { get; set; }
    }

    public class MyContext : DbContext
    {
        public DbSet<Harbor> Harbors { get; set; }
        public DbSet<Ship> Ships { get; set; }
        public DbSet<CrewMember> CrewMembers { get; set; }
        public DbSet<Rank> Ranks { get; set; }
        public DbSet<Clearance> Clearances { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());

            using (var context = new MyContext())
            {
                context.Database.Initialize(true);

                var harbor = new Harbor
                {
                    Ships = new HashSet<Ship>
                    {
                        new Ship
                        {
                            CrewMembers = new HashSet<CrewMember>
                            {
                                new CrewMember
                                {
                                    Rank = new Rank { Description = "Rank A" },
                                    Clearance = new Clearance { Description = "Clearance A" },
                                    Description = "CrewMember A"
                                },
                                new CrewMember
                                {
                                    Rank = new Rank { Description = "Rank B" },
                                    Clearance = new Clearance { Description = "Clearance B" },
                                    Description = "CrewMember B"
                                }
                            },
                            Description = "Ship AB"
                        },
                        new Ship
                        {
                            CrewMembers = new HashSet<CrewMember>
                            {
                                new CrewMember
                                {
                                    Rank = new Rank { Description = "Rank C" },
                                    Clearance = new Clearance { Description = "Clearance C" },
                                    Description = "CrewMember C"
                                },
                                new CrewMember
                                {
                                    Rank = new Rank { Description = "Rank D" },
                                    Clearance = new Clearance { Description = "Clearance D" },
                                    Description = "CrewMember D"
                                }
                            },
                            Description = "Ship CD"
                        }
                    },
                    Description = "Harbor ABCD"
                };

                context.Harbors.Add(harbor);
                context.SaveChanges();
            }

            using (var context = new MyContext())
            {
                DbSet<Harbor> dbSet = context.Set<Harbor>();
                IQueryable<Harbor> query = dbSet;
                query = query.Include(entity => entity.Ships);
                query = query.Include(entity => entity.Ships.Select(s => s.CrewMembers));
                query = query.Include(entity => entity.Ships.Select(s => s.CrewMembers.Select(cm => cm.Rank)));
                query = query.Include(entity => entity.Ships.Select(s => s.CrewMembers.Select(cm => cm.Clearance)));

                var sqlString = query.ToString();
                // see below for the generated SQL query

                var harbor = query.Single();

                Console.WriteLine("Harbor {0} Description = \"{1}\"",
                    harbor.HarborId, harbor.Description);
                foreach (var ship in harbor.Ships)
                {
                    Console.WriteLine("- Ship {0} Description = \"{1}\"",
                        ship.ShipId, ship.Description);
                    foreach (var crewMember in ship.CrewMembers)
                    {
                        Console.WriteLine("-- CrewMember {0} Description = \"{1}\"", 
                            crewMember.CrewMemberId, crewMember.Description);
                        Console.WriteLine("-- CrewMember {0} Rank Description = \"{1}\"",
                            crewMember.CrewMemberId, crewMember.Rank.Description);
                        Console.WriteLine("-- CrewMember {0} Clearance Description = \"{1}\"",
                            crewMember.CrewMemberId, crewMember.Clearance.Description);
                    }
                }

                Console.ReadLine();
            }
        }
    }
}
 

Outputtet er:

I henhold til din beskrivelse med fed skrift skulle jeg have:CrewMember 1 Beskrivelse ="Rank A" og samme rod for de andre 3 besætningsmedlemmer. Men det har jeg ikke.

Er der noget anderledes i mit testprogram sammenlignet med din kode, hvor du har fejlen?

Rediger

Den genererede SQL for forespørgslen (se linje var sqlString = query.ToString(); i kildekoden ovenfor er det følgende indholdet af sqlString ) er:

SELECT [Project1].[HarborId] AS [HarborId], [Project1].[Description] AS [Description], [Project1].[C2] AS [C1], [Project1].[ShipId] AS [ShipId], [Project1].[HarborId1] AS [HarborId1], [Project1].[Description1] AS [Description1], [Project1].[C1] AS [C2], [Project1].[CrewMemberId] AS [CrewMemberId], [Project1].[ShipId1] AS [ShipId1], [Project1].[RankId] AS [RankId], [Project1].[ClearanceId] AS [ClearanceId], [Project1].[Description2] AS [Description2], [Project1].[RankId1] AS [RankId1], [Project1].[Description3] AS [Description3], [Project1].[ClearanceId1] AS [ClearanceId1], [Project1].[Description4] AS [Description4] FROM ( SELECT [Extent1].[HarborId] AS [HarborId], [Extent1].[Description] AS [Description], [Join3].[ShipId1] AS [ShipId], [Join3].[HarborId] AS [HarborId1], [Join3].[Description1] AS [Description1], [Join3].[CrewMemberId] AS [CrewMemberId], [Join3].[ShipId2] AS [ShipId1], [Join3].[RankId1] AS [RankId], [Join3].[ClearanceId1] AS [ClearanceId], [Join3].[Description2] AS [Description2], [Join3].[RankId2] AS [RankId1], [Join3].[Description3] AS [Description3], [Join3].[ClearanceId2] AS [ClearanceId1], [Join3].[Description4] AS [Description4], CASE WHEN ([Join3].[ShipId1] IS NULL) THEN CAST(NULL AS int) WHEN ([Join3].[CrewMemberId] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1], CASE WHEN ([Join3].[ShipId1] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C2] FROM [dbo].[Harbors] AS [Extent1] LEFT OUTER JOIN (SELECT [Extent2].[ShipId] AS [ShipId1], [Extent2].[HarborId] AS [HarborId], [Extent2].[Description] AS [Description1], [Join2].[CrewMemberId], [Join2].[ShipId2], [Join2].[RankId1], [Join2].[ClearanceId1], [Join2].[Description2], [Join2].[RankId2], [Join2].[Description3], [Join2].[ClearanceId2], [Join2].[Description4] FROM [dbo].[Ships] AS [Extent2] LEFT OUTER JOIN (SELECT [Extent3].[CrewMemberId] AS [CrewMemberId], [Extent3].[ShipId] AS [ShipId2], [Extent3].[RankId] AS [RankId1], [Extent3].[ClearanceId] AS [ClearanceId1], [Extent3].[Description] AS [Description2], [Extent4].[RankId] AS [RankId2], [Extent4].[Description] AS [Description3], [Extent5].[ClearanceId] AS [ClearanceId2], [Extent5].[Description] AS [Description4] FROM [dbo].[CrewMembers] AS [Extent3] INNER JOIN [dbo].[Ranks] AS [Extent4] ON [Extent3].[RankId] = [Extent4].[RankId] LEFT OUTER JOIN [dbo].[Clearances] AS [Extent5] ON [Extent3].[ClearanceId] = [Extent5].[ClearanceId] ) AS [Join2] ON [Extent2].[ShipId] = [Join2].[ShipId2] ) AS [Join3] ON [Extent1].[HarborId] = [Join3].[HarborId] ) AS [Project1] ORDER BY [Project1].[HarborId] ASC, [Project1].[C2] ASC, [Project1].[ShipId] ASC, [Project1].[C1] ASC

  1. Returner værdi fra sql-script til shell-script

  2. Installation af Oracle 9i Developer Suite 2.0 på Windows

  3. Hvad er et godt databasedesign (skema) til en tilstedeværelsesdatabase?

  4. Indsættelse af billeder i en database