Entity Framework 4.2: несколько объектов, использующих одни и те же отношения «многие ко многим» - PullRequest
1 голос
/ 14 февраля 2012

У меня есть стол Путешественники :

CREATE TABLE [dbo].[Travelers](
    [TravelerId] [int] IDENTITY(1,1) NOT NULL,
    [FirstName] [nvarchar](25) NULL,
    [LastName] [nvarchar](50) NULL

стол Транспортеры и стол соединения TransporterTravelers

CREATE TABLE [dbo].[TransporterTravelers](
    [Transporter_TransporterId] [int] NOT NULL,
    [Traveler_TravelerId] [int] NOT NULL,

для создания отношений «многие ко многим» между путешественниками и перевозчиками.Я использовал классы POCO для создания сущностей Traveler и Transporter, и таблица соединений была создана автоматически (с использованием инициализатора CreateDatabaseIfNotExists).По мере продвижения проекта мы перешли к автоматическому созданию базы данных, потому что база данных теперь заполнена данными.Недавно мы добавили представление vwTravelersSummary для ускорения работы, которое обращается к таблице Travelers и нескольким другим таблицам, используя внутренние / левые объединения:

CREATE view [dbo].[vwTravelersSummary] as
SELECT
    tr.[TravelerId],
    tr.[FirstName],
    tr.[LastName],

    adr.[Street],
    adr.[Number], 
    adr.[PostalCode],
    adr.[Town],
FROM
    [dbo].[Travelers] tr
    LEFT JOIN (...)

Я создал POCO-класс, который сопоставлен с этимview:

[DataServiceKey("TravelerId")]
[MetadataType(typeof(TravelerSummaryMeta))]
[Table("vwTravelersSummary")]
public class TravelerSummary
{
    public TravelerSummary()
    {
    }

    [Key]
    public int TravelerId { get; set; }
    ... 
    public string Street { get; set; }
    public int? Number { get; set; }
    public string PostalCode { get; set; }
    public string Town { get; set; }
}

Мне также требовалось отношение многих ко многим между этой сущностью и транспортерами (мы используем службы данных, и нам нужно это отношение в перехватчике запросов).Поэтому я добавил следующий вызов Fluent API:

modelBuilder.Entity<TravelerSummary>()
    .HasMany(ts => ts.Transporters)
    .WithMany(/* No navigation from Transporter to TravelersSummary */)
    .Map(mc =>
        {
            mc.ToTable("TransporterTravelers");
            mc.MapLeftKey("Traveler_TravelerId");
            mc.MapRightKey("Transporter_TransporterId");
        }
    );

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

Неверное имя объекта 'dbo.TransporterTravelers1'.

(из-за условного наименования?).Поэтому я явно указал также исходные отношения «многие ко многим» между путешественниками и перевозчиками:

modelBuilder.Entity<Traveler>()
    .HasMany(t => t.Transporters)
    .WithMany(tr => tr.Travelers)
    .Map(mc =>
    {
        mc.ToTable("TransporterTravelers");
        mc.MapLeftKey("Traveler_TravelerId");
        mc.MapRightKey("Transporter_TransporterId");
    }
    );

Теперь я получаю следующую ошибку:

Указанная схема недопустима.Ошибки: (2219,6): ошибка 0019: EntitySet 'TravelerSummaryTransporter' со схемой 'dbo' и таблицей 'TransporterTravelers' уже определен.Каждый EntitySet должен ссылаться на уникальную схему и таблицу.

Как я могу решить эту проблему?Заранее спасибо!

1 Ответ

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

Вы не можете. EF не поддерживает отображение таблицы более одного раза, и отношение многие ко многим представлено отображением таблицы. Из-за этого вы не можете использовать таблицу в двух разных отношениях «многие ко многим» (даже если они на самом деле одинаковы, но EF об этом не знает).

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

...