Почему левое внешнее соединение? - PullRequest
11 голосов
/ 20 июня 2011

странный. (Наверное, совсем не странно)

У меня есть 3 объекта: Сотрудник, Рота и Отдел.

public class Employee
{
    public int Id { get; set; }
    public String Name { get; set; }
    public virtual Department Department { get; set; }
}

internal class EmployeeMapping : EntityTypeConfiguration<Employee>
{
    public EmployeeMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("UserId");

        HasRequired<Department>(a => a.Department).WithOptional().Map(a => a.MapKey("DepartmentId"));
    }
}

public class Department
{
    public int Id { get; set; }
    public String Name { get; set; }
}

internal class DepartmentMapping : EntityTypeConfiguration<Department>
{
    public DepartmentMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("DepartmentId");
    }
}

public class Rota
{
    public int Id { get; set; }
    public virtual Employee Employee { get; set; }
    public virtual Department Department { get; set; }
}

internal class RotaMapping : EntityTypeConfiguration<Rota>
{
    public RotaMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("RotaId");

        HasOptional<Employee>(a => a.Employee).WithOptionalDependent().Map(a => a.MapKey("EmployeeId"));
        HasOptional<Department>(a => a.Department).WithOptionalDependent().Map(a => a.MapKey("DepartmentId"));
    }
}

Не сложно, вообще-то. В Rota может быть назначен сотрудник и / или отдел, все это настраивается с помощью Fluent. Все мои ассоциации верны (схема идеальна), однако у меня странная странность.

Когда я выполняю myContext.Departments.FirstOrDefault() и смотрю на сгенерированный SQL, на Employee & Rota появляется LEFT OUTER JOIN . Почему это там?
Я не хочу этого делать. Может быть, мои отображения Fluent неверны? Я пробовал все виды, но не могу понять это. Я бы понял, если бы я хотел объект Rota, который присоединился бы к Департаменту. Но не наоборот!

Если я сделаю myContext.Departments.AsNoTracking().FirstOrDefault(), он не сделает LEFT OUTER JOIN's .

Есть идеи, ребята?

Ура, D

Ответы [ 3 ]

5 голосов
/ 20 июня 2011

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

internal class EmployeeMapping : EntityTypeConfiguration<Employee>
{
    public EmployeeMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("UserId");

        HasRequired<Department>(a => a.Department).WithMany()
                                                  .Map(a => a.MapKey("DepartmentId"));
    }
}

internal class RotaMapping : EntityTypeConfiguration<Rota>
{
    public RotaMapping()
    {
        HasKey(a => a.Id);
        Property(a => a.Id).HasColumnName("RotaId");

        HasOptional<Employee>(a => a.Employee).WithMany()
                                              .Map(a => a.MapKey("EmployeeId"));
        HasOptional<Department>(a => a.Department).WithMany()
                                                  .Map(a => a.MapKey("DepartmentId"));
    }
}

Ваше отображение правильно интерпретируется, когда база данных создается, и база данных выглядит правильно, но EF считает, что вы отображаете все отношения как один-к-одному.Это сбивает с толку EF, и он будет генерировать запросы, используемые один-к-одному для создания внутренних ссылок на сущности.Эти левые соединения необходимы для отношения один-к-одному, когда вы сообщаете EF, что зависимые объекты являются необязательными - EF не знает, существуют ли они, пока не загрузит их ключи.

0 голосов
/ 20 июня 2011

У меня есть теория.Левое внешнее соединение исчезает при отключении отслеживания изменений.Также у Сотрудника и Рота есть ссылки на Отдел.

Таким образом, моя теория заключается в том, что с отслеживанием изменений в Entity Framework пытается загрузить все объекты со ссылкой на отдел на случай, если потребуется каскадное обновление для отдела.

Другими словамисчитает, что изменение отдела может привести к изменению ссылки на сотрудника или сотрудника отдела, поэтому он загружает все на всякий случай.

0 голосов
/ 20 июня 2011

Я ни в коем случае не эксперт, и я просто догадываюсь здесь. Но не могли бы вы попробовать выполнить запрос так, как это делает структура сущностей, а затем попытаться сделать это так, как вам бы хотелось, чтобы увидеть запрос и опубликовать разницу во времени. Может быть, здесь есть какая-то структура сущностей, но я сомневаюсь в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...