Несколько внешних ключей в одной платформе Table Entity Framework 4.3.1 - PullRequest
0 голосов
/ 09 марта 2012

Я новичок в EF и много дней читал Учебники и Google, чтобы найти решение для моей проблемы.Извините, мой английский не самый лучший, но я хочу попытаться сформулировать мой вопрос.

Модель данных

Моя модель создана из базы данных SQL Express (сокращенная версия для лучшего понимания):

См. Изображение :

Создать образец данных

Теперь я пытаюсь заполнить свою БД демонстрационными данными.Я создаю объект Liegenschaft и заполняю данные в этом.Простая версия для отображения моего дерева данных (реальная версия может иметь много объектов HAUS в ObjektMenge = List и ObjektMenge = List тоже.

List<Liegenschaft> LL = new List<Liegenschaft>(); 

        for (int i = 0; i < 2; i++)
        {
            Liegenschaft L = new Liegenschaft()
            {
                Strasse = "demostreet1",
                HausMenge = new List<Haus>(){ 
                new Haus(){ 
                    Nummer = 21, 
                    ObjektMenge = new List<Objekt>(){
                        new Objekt(){ 
                            Zimmer = 221,
                            MieterMenge= new List<Mieter>(){
                                new Mieter(){
                                    Name="DemoName",
                                    MietzinsMenge= new List<Mietzins>(){
                                        new Mietzins(){
                                            StartDate=System.DateTime.Now,
                                            EndDate=System.DateTime.Now},
                                        new Mietzins(){
                                            StartDate=System.DateTime.Now,
                                            EndDate=System.DateTime.Now}
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };
         LL.Add(L);
        }

Попробуйте сохранить в БД

foreach (Liegenschaft Lieg in LL)
{
    using (var db = new ImmoReportsEntities())
    {
        db.Liegenschaft.Add(Lieg);
        db.SaveChanges();
    }  
 }

Проблема

Все мои демонстрационные данные могут быть сохранены в базе данных, и все FK автоматически создаются правильно, когда MietzinsMenge НЕ заполнены!

Если у меня есть данные в этом MietzinsMenge, выдает ошибку: FK_Mietzins_Objektимеет идентичный первичный ключ!

Info

Я не использую формы для вставки данных в эту таблицу. Все данные поступают из другой (внешней) БД, и я хочу импортировать ее в свою БД.Могу ли я импортировать эти MietZins тоже в мое дерево данных и иметь все эти FK (LiegenschftId, ObjektId, MieterId).

1 Ответ

0 голосов
/ 09 марта 2012

Не похоже, что вы устанавливаете значения первичного ключа для своих объектов Mietzins.Вам нужно либо установить значения первичного ключа, прежде чем пытаться сохранить его в базе данных, или сказать EF, что первичные ключи будут сгенерированы базой данных.

Способ указания ключа, сгенерированного базой данных, зависит от того,вы используете код сначала или база данных сначала.В Code First он обычно включен по умолчанию для целочисленных типов ключей, или вы можете использовать DatabaseGeneratedAttribute и установить Identity.Для Database First вы используете EF Designer и устанавливаете для фасета StoreGenerated свойства ключа значение Identity.

Я заново создал вашу модель, как показано на диаграмме, используя следующие классы и сопоставления Code First.(Я понимаю, что вы, вероятно, не используете Code First, но для меня это был самый простой способ создать ту же модель со всеми связями, как показано на диаграмме.)

public class Mietzins
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int MieterId { get; set; }
    public int ObjektId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public Mieter Mieter { get; set; }
    public Objekt Objekt { get; set; }
}

public class Mieter
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int ObjektId { get; set; }
    public string Name { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public Objekt Objekt { get; set; }
}

public class Objekt
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int HausId { get; set; }
    public int Zimmer { get; set; }

    public Haus Haus { get; set; }
    public Liegenschaft Liegenschaft { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public ICollection<Mieter> MieterMenge { get; set; }
}

public class Liegenschaft
{
    public int Id { get; set; }
    public string Strasse { get; set; }
    public int UserId { get; set; }

    public ICollection<Haus> HausMenge { get; set; }
    public ICollection<Mieter> MieterMenge { get; set; }
    public ICollection<Mietzins> MietzinsMenge { get; set; }
    public ICollection<Objekt> ObjektMenge { get; set; }
}

public class Haus
{
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int Nummer { get; set; }

    public ICollection<Objekt> ObjektMenge { get; set; }
    public Liegenschaft Liegenschaft { get; set; }
}

Контекст:

public class ImmoReportsEntities : DbContext
{
    public DbSet<Liegenschaft> Liegenschaft { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.HausMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.MieterMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Liegenschaft>()
            .HasMany(e => e.ObjektMenge)
            .WithRequired(e => e.Liegenschaft)
            .HasForeignKey(e => e.LiegenschaftId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Haus>()
            .HasMany(e => e.ObjektMenge)
            .WithRequired(e => e.Haus)
            .HasForeignKey(e => e.HausId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Objekt>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Objekt)
            .HasForeignKey(e => e.ObjektId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Objekt>()
            .HasMany(e => e.MieterMenge)
            .WithRequired(e => e.Objekt)
            .HasForeignKey(e => e.ObjektId)
            .WillCascadeOnDelete(false);

        modelBuilder.Entity<Mieter>()
            .HasMany(e => e.MietzinsMenge)
            .WithRequired(e => e.Mieter)
            .HasForeignKey(e => e.MieterId)
            .WillCascadeOnDelete(false);
    }
}

Затем я выполнил ваш код точно так же, как в вопросе, и он работал нормально.

Затем я изменил первичный ключ Mietzins, чтобы он больше не генерировался из базы данных:

public class Mietzins
{
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public int Id { get; set; }
    public int LiegenschaftId { get; set; }
    public int MieterId { get; set; }
    public int ObjektId { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }

    public Liegenschaft Liegenschaft { get; set; }
    public Mieter Mieter { get; set; }
    public Objekt Objekt { get; set; }
}

Я снова запустил код и получил следующее исключение:

Необработанное исключение: System.Data.Entity.Infrastructure.DbUpdateException: при обновлении записей произошла ошибка.Смотрите внутреннее исключение для деталей.---> System.Data.UpdateException: при обновлении записей произошла ошибка.Смотрите внутреннее исключение для деталей.---> System.Data.SqlClient.SqlException: Нарушение ограничения PRIMARY KEY 'PK_Mietzins'.Невозможно вставить дубликат ключа в объект 'dbo.Mietzins'.Оператор был прерван.

Если это не то же самое, что и исключение, которое вы видите, пожалуйста, опубликуйте свой код, полное сообщение об исключении и трассировку стека, и я еще раз посмотрю.

...