Мысли о том, как перемещаться между отношениями «многие ко многим» в Entity Framework 4.1 - PullRequest
1 голос
/ 14 февраля 2012

Я не большой поклонник необходимости размещать свойства навигации на объектах, которые совместно используются несколькими объектами в модели. Вот пример того, о чем я говорю:

    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.

Одной из мыслей было иметь ICollection<SomeEntity> Entites для Attachemnt, но не уверен, что это сработает, потому что я сталкивался с проблемами сопоставления с этим раньше. Еще одна мысль, которая у меня была, заключалась в том, чтобы вручную переходить от вложений к сущностям, но это означало бы необходимость написания метода для передачи коллекции объектов назад и определения их типов.

У меня EF генерирует таблицы ссылок вот так:

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

Глядя на мою таблицу «Вложения», мы не видим FK ни в одной из таблиц ссылок. Это имеет смысл, потому что я не вернусь к ним.

1 Ответ

1 голос
/ 15 февраля 2012

Если вы беспокоитесь о отложенной загрузке, вы можете сделать свойство навигации не виртуальным, чтобы оно никогда не сработало при отложенной загрузке.

Или вы можете сделать свойство навигации частным, а затем получить доступ к содержимому вконтролируемым образом.Как только вы сделаете свойство навигации приватным, вам нужно будет использовать один из приемов для сопоставления частных свойств с помощью API Code First.Для простоты я использую тот, который встраивает 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());
}

Затем вы можете получить доступ к пользователям изнутри Attachment в любомкак вы хотите, или показывать пользователям методы и т. д.

Вы также можете использовать API отслеживания изменений DbContext для доступа к ним из любого места, где у вас есть контекст.Например:

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

Если вы действительно вообще не хотите иметь свойство навигации, вы можете перейти к ObjectContext и получить RelatedEnd для коллекции, которая будет EntityCollection.Это довольно сложный код по ряду причин, включая необходимость знать концептуальные имена моделей для ассоциации и конечных имен, которые можно найти, выгрузив EDMX.Я бы избежал такого подхода, если это вообще возможно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...