关于如何在实体框架4.1中的多对多关系之间导航的思考

时间:2012-02-14 19:23:18

标签: entity-framework entity-framework-4.1

我不喜欢将导航属性放在模型中多个实体共享的对象上。以下是我所谈论的一个例子:

    public abstract class SomeEntity
    {
       public Guid Id {get;set;         
       public virtual ICollection<Attachment> Attachements {get;set;}
    }

    public class User: SomeEntity
    {
         ...
    }

    public class Thing: SomeEntity
    {
         ...
    }

    public class Attachment
    {
       public Guid Id {get;set;}         
       ...
    }

我已经厌倦了避免在用户和事物的附件实体上拥有导航属性。我的想法是避免我们使用Lazy Loading的情况。

有一种想法是在一个Attachemnt上有一个ICollection<SomeEntity> Entites,但不确定它会起作用,因为我之前遇到了映射问题。我的另一个想法是手动从附件导航到实体,但这意味着必须编写一个方法来传回一组对象并找出它们的类型。

我正在使用EF生成这样的链接表:

HasMany(e => e.Attachments).WithMany().Map(m => { m.MapLeftKey("AttachmentId");
                                                                  m.MapRightKey("UserId");
                                                                  m.ToTable("User_Attachments");
            });

查看我的附件表,没有FK回到任何链接表。这是有道理的,因为我没有回到他们身边。

1 个答案:

答案 0 :(得分:1)

如果您担心延迟加载,那么您可以使导航属性不是虚拟的,这样它就不会延迟加载。

或者您可以将导航属性设为私有,然后以受控方式访问内容。一旦将导航属性设为私有,您将需要使用其中一个技巧来使用Code First API映射私有属性。为简单起见,我使用的是在实体中嵌入EntityConfiguration的那个:

public class Attachment
{
    public Guid Id { get; set; }

    private ICollection<User> Users { get; set; }

    public class AttachmentConfiguration : EntityTypeConfiguration<Attachment>
    {
        public AttachmentConfiguration()
        {
            HasMany(e => e.Users)
                .WithMany(e => e.Attachements)
                .Map(m =>
                     {
                         m.MapLeftKey("UserId");
                         m.MapRightKey("AttachmentId");
                         m.ToTable("User_Attachments");
                     });
        }
    }
} 

在OnModelCreating:

中添加此配置
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new Attachment.AttachmentConfiguration());
}

然后,您可以以任何您想要的方式从“附件”内部访问用户,或者从方法等中公开用户。

您还可以使用DbContext更改跟踪器API从您拥有上下文的任何位置访问它们。例如:

var users = context.Entry(attachment).Collection<User>("Users").CurrentValue;

如果你真的不想要导航属性,那么你可以下拉到ObjectContext并获取集合的RelatedEnd,它将是一个EntityCollection。由于许多原因,这是非常棘手的代码,包括需要知道关联和结束名称的概念模型名称,您可以通过转储EDMX找到它们。如果可能的话,我会避免这种做法。