1

我是一名 Java 人,我正在努力学习 .Net 领域。我正在学习的其中一件事是 EF4,我注意到了这个有趣的事情。当您声明一个与另一个实体具有 1:n 关系的实体时,您必须执行以下操作:

public int CategoryId { get; set; }
public virtual Category Category { get; set; }

我的问题是:

框架需要两个声明是否有充分的理由?

在 Java 世界中,该框架足够智能,可以确定主键是什么,并将该记录添加到 DB 中,而不必在实体类上具有单独的字段。为什么.Net 没有在这个小而烦人的问题上效仿?

4

2 回答 2

1

你不必那样做。事实上你不应该因为你可以让你的对象处于不一致的状态。假设您有:

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

public class SomeClass {
    public Int32 Id { get; set; }
    public virtual Category Category { get; set; }
}

这是有效的。您只需要在其配置中告诉 EF 如何找到外键。基于以上内容,它将尝试使用SomeClass.Category_Id,但您可以随意更改它。

编辑:如果要更改外键,可以通过添加配置类并在OnModelCreating事件期间添加它来实现:

internal class ForSomeClassEntities : EntityTypeConfiguration<SomeClass> {
    public ForSomeClassEntities(String schemaName) {
        this.HasRequired(e => e.Category)
            .WithMany()
            .Map(map => map.MapKey("CategoryId"));
        this.ToTable("SomeClass", schemaName);
    }
}

在您的覆盖Context类中:

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

    modelBuilder.Configurations
        .Add(new ForSomeClassEntities("SomeSchema"))
        ;
}

使用上面相同的类会告诉 EF 寻找一个被调用的外键属性SomeClass.CategoryId

于 2012-08-08T13:56:37.043 回答
1

当您向模型添加虚拟集合/模型时,实体框架会自动 <ClassName>Id 向其添加一个字段。出于可读性目的,开发人员通常决定显式声明<ClassName>Id,以便其他开发人员明确知道它的存在(不依赖于配置的约定)。例如,教程就是这种情况,因为他们想让事情变得清晰。

实体框架足够聪明,可以使用<ClassName>Id已经显式声明的现有实体。因此,解决对该主题的其他响应,它不会导致不一致的状态。此外,从性能的角度来看,它仍然符合延迟加载模式,因为预加载int(在本例中为 ID)仍然非常快(甚至无法与预加载整个对象相比)。

于 2017-04-05T16:25:27.163 回答