Необязательное свойство навигации не загружается - PullRequest
1 голос
/ 08 ноября 2011

Не могу понять, почему Entity Framework (4.1, Code First) не материализует необязательное свойство навигации.

POCO которые:

public class PlanMember {
    public Int64 Id { get; set; }

    public String FirstName { get; set; }

    public virtual SystemUser CaseManager { get; set; }

    public String LastName { get; set; }

    public virtual PlanMemberStatus Status { get; set; }
}

public class SystemUser {
    public String EMail { get; set; }

    public String FirstName { get; set; }

    public String Id { get; set; }

    public String LastName { get; set; }
}

public class PlanMemberStatus {
    public Int32 Id { get; set; }

    public String Code { get; set; }
}

Классы конфигурации:

public class ForPlanMemberEntities:EntityTypeConfiguration<PlanMember> {
    public ForPlanMemberEntities(String schemaName) {
        this.HasOptional(e => e.CaseManager)
            .WithMany()
            .Map(m => m.MapKey("CaseManagerID"));
        this.HasRequired(e => e.Status)
            .WithMany()
            .Map(m => m.MapKey("StatusID"));
        this.ToTable("PlanMember", schemaName);
    }
}

public class ForSystemUserEntities:EntityTypeConfiguration<SystemUser> {
    public ForSystemUserEntities(String schemaName) {
        this.ToTable("SystemUser", schemaName);
    }
}

public class ForPlanMemberStatusEntities:EntityTypeConfiguration<PlanMemberStatus> {
    public ForPlanMemberStatusEntities(String schemaName) {
        this.ToTable("PlanMemberStatus", schemaName);
    }
}

Контекст:

public class Context:DbContext {
    public DbSet<PlanMember> PlanMemberDbSet { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder) {
        base.OnModelCreating(modelBuilder);

        var schemaName = Properties.Settings.Default.SchemaName;
        modelBuilder.Configurations
            .Add(new Configuration.ForPlanMemberEntities(schemaName))
            .Add(new Configuration.ForPlanMemberStatusEntities(schemaName))
            .Add(new Configuration.ForSystemUserEntities(schemaName))
            ;
    }
}

На основании этой конфигурации, если я выполню запрос, подобный следующему, он не заполнит свойство CaseManager. Свойство PlanMemberStatus загружается просто отлично.

var test = (from member in PlanMemberDbSet
            where member.CaseManager != null
            select member).First();
var cm = test.CaseManager;

В моем примере cm всегда null, несмотря на то, что - по логике - это должно быть невозможно. Есть мысли?

РЕДАКТИРОВАТЬ - Если я сделаю PlanMemberDbSet.Include("CaseManager"), то это работает, как ожидалось. Почему это необходимо? В других случаях мне не приходилось это делать.

1 Ответ

1 голос
/ 08 ноября 2011

Я предполагаю, что значение столбца внешнего ключа CaseManagerID в таблице PlanMember отличается от значения столбца первичного ключа Id в таблице SystemUser - отличается для .NET, но не для SQL Server (со стандартным система сортировки), например, различаются по корпусу: « a » в CaseManagerID, но « A » в Id.

Запрос для != null (переводится на IS NOT NULL в SQL) работает, поэтому вы действительно получаете только PlanMember сущностей, которым в базе данных назначен SystemUser. Также запрос с помощью CaseManager (вызванный отложенной загрузкой) правильно выполняется в базе данных (INNER JOIN) и передается клиенту. Даже материализация объекта работает (в контексте есть 2 объекта). Но EF не может связать загруженный PlanMember с загруженным CaseManager, потому что ключи не идентичны (например, в отношении заглавных / строчных букв). В результате ваше свойство навигации равно null.

Этого не происходит со свойством навигации Status, потому что ключ Int32.

Проблема выглядит тесно связанной с этой: Код EF 4.1 Первая ошибка в Find / Update. Любое решение? Стоит ли сообщать об этом?

...