Entity Framework 4.1. Внешний ключ свободного отображения и внешний объект со строковым ключом. - PullRequest
0 голосов
/ 26 сентября 2011

Я перехожу от отображения EDMX к отображению EF 4.1 DbContext и Fluent, и я хочу отобразить как строковый внешний ключ, так и внешний объект, используя свободный API.У меня есть сотрудник с дополнительным офисом.Я хотел бы, чтобы OfficeId и объект Office в классе Employee (это все только для чтения, и мне не нужно иметь возможность сохранять эти объекты).Объекты с ключами int работают нормально, но я пробовал несколько с использованием строковых ключей и получил тот же результат - поле OfficeId заполняется, но объект Office возвращается как ноль.Проверка в профилировщике SQL данных запрашивается, но объект office не заполняется.

public partial class Employee
{
    public int Id { get; set; }
    // snip irrelevant properties
    public Office Office { get; set; }  // this is (incorrectly) always null
    public string OfficeId { get; set; }
    public WorkGroup WorkGroup { get; set; } // this one with the int key is fine
    public int? WorkGroupId { get; set; }
    // snip more properties
}

public partial class Office
{
    public string Id { get; set; }
    public string Description { get; set; }
}

public partial class WorkGroup
{
    public int Id { get; set; }
    public string Code { get; set; }
}

После обратной связи с Ладиславом ниже я сопоставляю его следующим образом в OnModelCreating

modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("Employee", "ExpertQuery");
modelBuilder.Entity<Office>().HasKey(d => d.Id).ToTable("Office", "ExpertQuery");
modelBuilder.Entity<WorkGroup>().HasKey(d => d.Id).ToTable("WorkGroup", "ExpertQuery");

modelBuilder.Entity<Employee>()
    .HasOptional(a => a.Office)
    .WithMany()
    .Map(x => x.MapKey("OfficeId")); // this one does not work
modelBuilder.Entity<Employee>()
            .HasOptional(e => e.WorkGroup)
            .WithMany()
            .HasForeignKey(e => e.WorkGroupId); // this one works fine

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

var employees = expertEntities.Employees.Include("Office").Include("WorkGroup").Take(10).ToList();

Если я опускаю поле OfficeId в Employee и настраиваю сопоставление следующим образом:

modelBuilder.Entity<Employee>()
    .HasOptional(e => e.BusinessEntity)
    .WithMany()
    .Map(x => x.MapKey("OfficeId"));

Затем заполняется объект office, ноМне нужно поле OfficeId в объекте Employee.

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

Ну, я нашел проблему - это проблема данных - значения строки первичного ключа были дополнены пробелами, а значения внешнего ключа не были (!).Хотя SQL правильно соединяет таблицы (игнорируя заполнение) и выбирает правильные данные, похоже, что EF не сопоставит их обратно с правильными объектами, так как .NET более суетлив, чем SQL в отношении конечных пробелов.

0 голосов
/ 26 сентября 2011

Это не правильное отображение.Если у вас есть свойство FK, вы не можете использовать Map и MapKey.Это для сценариев, где у вас нет этого свойства.Попробуйте это:

modelBuilder.Entity<Employee>()
            .HasOptional(a => a.Office)
            .WithMany()
            .HasForeignKey(a => a.OfficeId);

Кроме того, первая часть сопоставления сущностей с таблицей, скорее всего, неверна.Map используется для сценариев наследования и разделения сущностей.Вы ищете ToTable:

modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("ExpertQuery.Employee");

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

modelBuilder.Entity<Employee>().HasKey(d => d.Id).ToTable("Employee", "ExpertQuery");
0 голосов
/ 26 сентября 2011

Ваше настроенное сопоставление просто конфликтует из-за того, что вы уже ввели свойство OfficeId строкового типа.Посмотрите, что произойдет, если вы удалите свойство OfficeId из определения Employee или измените его на тип int.

...