Отображение таблиц ассоциаций в коде EF 4.1 первым - PullRequest
6 голосов
/ 01 ноября 2011

Я не уверен, как отобразить следующие таблицы ниже в EF 4.1 code first и какие объекты мне нужны для представления таблиц.Как получить список характеристик продукта?

В настоящее время у меня есть только класс Product.

Products Table:
Id
Name
IsActive

ProductSpecification Table:
ProductId
SpecificationId

Specifications Table:
Id
Name
IsActive

ProductSpecifications - это таблица ассоциации.В моем классе контекста также определено следующее:

public DbSet<Product> Products { get; set; }

РЕДАКТИРОВАТЬ

Пожалуйста, смотрите мой обновленный исходный пост.Я изменил идентификатор таблиц продуктов и спецификаций.

В моем классе контекста у меня есть следующее:

public DbSet<Product> Products { get; set; }
public DbSet<Specification> Specifications { get; set; }

В моем хранилище есть следующее:

public Product GetById(int id)
{
     return db.Products
          .Include("Specifications")
          .SingleOrDefault(x => x.Id == id);
}

Мой Product class (частично):

public class Product : IEntity
{
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
     public ICollection<Specification> Specifications { get; set; }
}

Мой Specification class:

public class Specification : IEntity
{
     public int Id { get; set; }
     public string Name { get; set; }
     public bool IsActive { get; set; }
     public ICollection<Product> Products { get; set; }
}

Это все, что я сделал из ответа Слаумы.Я не делал сопоставление вручную так, как он сказал, что я должен, но сначала мне нужно понять следующее:

Учитывая мои классы и таблицы сверху, что именно говорится в соглашениях об именах EF 4.1 о том, как он обрабатываеттаблицы ассоциаций?Причина, по которой я спрашиваю, состоит в том, что я получаю следующую ошибку в своем методе GetById:

Invalid object name 'dbo.SpecificationProducts'.

EDIT 2

Я забыл упомянуть следующее :) Продуктможет иметь в качестве значения высоту спецификации.И для этой высоты мне нужно указать значение.Как 100 дюймов.Поэтому я изменил таблицу ProductSpecifications, чтобы в ней был столбец значений с именем SpecificationValue, этот столбец будет содержать значение 100 дюймов.Как бы я изменил код, чтобы получить это значение?Мне нужно отобразить это на моем видении.

1 Ответ

11 голосов
/ 01 ноября 2011

В отношении «многие ко многим» вы определяете только классы для сущностей, которые хотите связать, но не сущности для таблицы сопоставления.Эта таблица «скрыта» в вашей модели и управляется Entity Framework автоматически.Таким образом, вы можете определить эти классы:

public class Product
{
    public int ProductId { get; set; }
    public string Name { get; set; }

    public ICollection<Specification> Specifications { get; set; }
}

public class Specification
{
    public int SpecificationId { get; set; }
    public string Name { get; set; }

    public ICollection<Product> Products { get; set; }
}

Этого обычно достаточно для определения отношения «многие ко многим».EF создаст таблицу соединений из этого сопоставления.Если у вас уже есть такая таблица в базе данных и ее наименование не соответствует в точности соглашениям об именах Entity Framework, вы можете определить отображение вручную в Fluent API:

modelBuilder.Entity<Product>()
    .HasMany(p => p.Specifications)
    .WithMany(s => s.Products)
    .Map(c =>
        {
            c.MapLeftKey("ProductId");
            c.MapRightKey("SpecificationId");
            c.ToTable("ProductSpecification");
        });

Редактировать

Затем можно загрузить спецификации продукта, используя Include, например:

var productWithSpecifications = context.Products
    .Include(p => p.Specifications)
    .SingleOrDefault(p => p.ProductId == givenProductId);

Это приведет к загрузке продукта вместе со спецификациями.Если вам нужны только спецификации для данного идентификатора продукта, вы можете использовать следующее:

var specificationsOfProduct = context.Products
    .Where(p => p.ProductId == givenProductId)
    .Select(p => p.Specifications)
    .SingleOrDefault();

..., которое возвращает набор спецификаций.

Редактировать 2

Соглашения об именах EF Code-First будут предполагать имя объединяемой таблицы, созданной как комбинация двух связанных имен классов, и затем ее перемножать.Таким образом, без явного сопоставления имени вашей таблицы ProductSpecification EF примет ProductSpecifications (Plural) и создаст запросы с этим именем в качестве имени таблицы.Поскольку эта таблица не существует в базе данных, вы получаете исключение " Неверное имя объекта 'dbo.SpecificationProducts'. " при выполнении запроса.Итак, вы должны либо переименовать таблицу в базе данных, либо использовать приведенный выше код сопоставления.

Изменить 3

Я настоятельно рекомендую использовать явное сопоставление в любом случаепотому что имя объединяющей таблицы EF предполагает, что зависит от порядка DbSets в вашем контексте .При изменении порядка этих наборов таблица соединения может составлять SpecificationProducts.Без явного сопоставления с фиксированным именем таблицы (как правило, неважно) замена наборов в контексте может привести к поломке вашего рабочего приложения.

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