我不喜欢将导航属性放在模型中多个实体共享的对象上。以下是我所谈论的一个例子:
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回到任何链接表。这是有道理的,因为我没有回到他们身边。
答案 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找到它们。如果可能的话,我会避免这种做法。