M: M Mapping - EF 4.3 CodeFirst (существующая база данных) - PullRequest
1 голос
/ 29 марта 2012

У меня есть две таблицы (Таблица A, Таблица B), объединенные с таблицей соединения (TableAB) с 3 столбцами полезной нагрузки.Под полезной нагрузкой я имею в виду столбцы, кроме Id, TableAId и TableBId.

Я могу успешно вставить во все таблицы, но мне нужно вставить данные в один из столбцов полезной нагрузки на Insert.Я использую EF 4.3, Fluent API.Кто-нибудь может помочь?Заранее спасибо.

    public class Organisation : EntityBase<int>, IAggregateRoot
       {
    public string Name { get; set; }
    public string Url { get; set; }
    public int CountryId { get; set; }
    public int? OwnershipTypeId { get; set; }
    public int OrganisationStatusId { get; set; }

    public virtual ICollection<Feature> Features { get; set; }
    public virtual ICollection<OrganisationType> OrganisationTypes { get; set; }
    public virtual ICollection<PricePlan> PricePlans { get; set; }
    public virtual ICollection<User> Users { get; set; }

}

    public class User: EntityBase<Guid>, IAggregateRoot
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string JobTitle { get; set; }
    public int?  PhoneCallingCodeId       { get; set; }
    public int?  PhoneAreaCode{ get; set; }
    public string PhoneLocal { get; set; }
    public int? MobileCallingCodeId { get; set; }
    public int? MobileAreaCode { get; set; }
    public string MobileLocal { get; set; }      

    public virtual ICollection<Organisation.Organisation> Organisations { get; set; }

}

   public class OrganisationUser : EntityBase<int>, IAggregateRoot
{
    public DateTime StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public int OrganisationRoleId {get; set;}//Foreign Key - have tried leaving it out, tried it as public virtual Organisation Organisation {get;set;
    public bool IsApproved { get; set; }
}

     public class SDContext : DbContext 
{      

    public ObjectContext Core
    {
        get
        {
            return (this as IObjectContextAdapter).ObjectContext;
        }
    }
  public IDbSet<User> User { get; set; }

  public IDbSet<Organisation> Organisation { get; set; }

  protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Organisation>().HasMany(u => u.Users).WithMany(o => o.Organisations).Map(m =>
        {
            m.MapLeftKey("OrganisationId");
            m.MapRightKey("UserId");
            m.ToTable("OrganisationUser");
        });

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

1 Ответ

2 голосов
/ 30 марта 2012

Ваше отображение не соответствует вашим целям. Если вы хотите рассматривать OrganisationUser как промежуточную сущность между Organisation и User, вы должны создать отношения между Organisation и OrganisationUser и между User и OrganisationUser, а не между Organisation и User.

Из-за промежуточного объекта, который содержит свои скалярные свойства, вы не можете создать отображение «многие ко многим». EF не поддерживает отношения «многие ко многим» с «полезной нагрузкой». Вам нужны два отношения один ко многим:

public class Organisation : EntityBase<int>, IAggregateRoot
{
    // ...
    // this replaces the Users collection
    public virtual ICollection<OrganisationUser> OrganisationUsers { get; set; }
}

public class User : EntityBase<Guid>, IAggregateRoot
{
    // ...
    // this replaces the Organisations collection
    public virtual ICollection<OrganisationUser> OrganisationUsers { get; set; }
}

public class OrganisationUser : EntityBase<int>, IAggregateRoot
{
    public int OrganisationId { get; set; }
    public Organisation Organisation { get; set; }

    public Guid UserId { get; set; }
    public User User { get; set; }

    // ... "payload" properties ...
}

В Fluent API вы должны заменить отображение «многие ко многим» следующим:

modelBuilder.Entity<Organisation>()
    .HasMany(o => o.OrganisationUsers)
    .WithRequired(ou => ou.Organisation)
    .HasForeignKey(ou => ou.OrganisationId);

modelBuilder.Entity<User>()
    .HasMany(u => u.OrganisationUsers)
    .WithRequired(ou => ou.User)
    .HasForeignKey(ou => ou.UserId);

Ваш производный DbContext может также содержать отдельный набор для сущности OrganisationUser:

public IDbSet<OrganisationUser> OrganisationUsers { get; set; }

Теперь очевидно, как вы записываете что-то в промежуточную таблицу:

var newOrganisationUser = new OrganisastionUser
{
    OrganisationId = 5,
    UserId = 8,
    SomePayLoadProperty = someValue,
    // ...
};

context.OrganisastionUsers.Add(newOrganisastionUser);
context.SaveChanges();

Если вы хотите убедиться, что каждая пара OrganisationId и UserId может существовать в таблице ссылок только один раз, было бы лучше создать составной первичный ключ из этих двух столбцов, чтобы обеспечить уникальность в базе данных. использования отдельного Id. В Fluent API это будет:

modelBuilder.Entity<OrganisationUser>()
    .HasKey(ou => new { ou.OrganisationId, ou.UserId });

Подробнее о модели такого типа и о том, как с ней работать, можно узнать здесь:

Сначала создайте код, многие ко многим, с дополнительными полями в таблице ассоциаций

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