2012-08-08 72 views
1

我是一个Java人,我正在学习.NET领域。我学习的一件事是EF4,我注意到这个有趣的事情。当你声明与1的实体:N关系到另一个实体,你必须做这样的事情:为什么我需要C#EF中的ID和虚拟集合?

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

我的问题是:

是否有一个很好的理由,该框架既需要声明?

在Java世界中,框架非常聪明,可以确定主键是什么,并将该记录添加到数据库中,而无需在实体类上具有单独的字段。为什么.Net在这个小问题上效仿,但令人讨厌的问题呢?

+1

你不需要两个:http://stackoverflow.com/a/5282275/270591+在答案的末尾的链接。两个链接更多:http://stackoverflow.com/questions/4703378/ef4-independent-associations-why-avoid-them和http://stackoverflow.com/questions/9253234/what-is-the-point-of-创建外键关键属性当使用实体框架 – Slauma 2012-08-08 15:20:20

+0

@Slauma,谢谢你的额外信息。这真的有助于澄清一些 - 我没有意识到这些是不同类型的关联。如果您将其作为答案张贴,我想接受它。 – ametren 2012-08-08 17:07:00

+0

你应该接受@ Yuck的回答。他非常清楚地解释说,你*可以在没有FK属性的情况下工作,举例和一切,这是你的问题,他回答了。我只对“你不应该”使用FK属性有一点否决权。但这更像是一场有争议的辩论。你会发现人们说“你应该”的同样经常的答案。 – Slauma 2012-08-08 18:35:40

回答

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的外键属性。

+0

谢谢,这就是有趣的 - 那么为什么我会按照我在所有教程中描述的方式来看待它? – ametren 2012-08-08 13:57:42

+1

@ametren:因为它更容易处理。出于这个原因,我不同意Yuck“你不应该”使用FK属性。 – Slauma 2012-08-08 15:26:01

+0

@Slauma我会同意不同意,只是补充一点,因为“*更容易*”并不意味着这是一个很好的设计实践。例如,WebForms **非常容易使用,但页面模型非常可怕。 – Yuck 2012-08-08 17:39:24

0

当您添加一个虚拟集合/模型到模型,实体框架自动添加一个<ClassName>Id域将其。为了便于阅读,开发人员通常决定明确声明<ClassName>Id,以便其他开发人员明确知道它在那里(不依赖于约定而不是配置)。例如,教程就是这种情况,因为他们想要说清楚。

实体框架足够智能,可以使用现有的<ClassName>Id(如果已经明确声明)。因此,处理对这个主题的其他回应,它不会导致不一致的状态。另外,从性能的角度来看,它仍然适合懒惰加载模式,因为预加载int(在这种情况下,ID)仍然非常快(甚至与预加载整个对象的程度相差甚远)。

相关问题