Entity Framework не сохраняет всю информацию в базу данных - PullRequest
2 голосов
/ 21 января 2020

У меня возникла проблема, которую я пытался решить, но не смог. По сути, у меня есть метод, который я получаю в качестве параметра одну строку и одну сериализованную карту из ajax post. Все, что касается этого, работает очень хорошо, за исключением того факта, что у меня, например, один и тот же FileId с другим UseCaseId , потому что тогда сохраняется только одна информация, а не обе.

** UseCaseId и FileId ** являются внешними ключами из других таблиц.

Отношение:

modelBuilder.Entity<Content>()
        .HasIndex(ct => ct.FileId)
        .IsUnique(false);
    modelBuilder.Entity<Content>()
        .HasIndex(ct => ct.UseCaseId)
        .IsUnique(false);

    modelBuilder.Entity<Content>()
        .HasKey(cn => cn.ContentId);
    modelBuilder.Entity<Content>()
        .HasOne(cn => cn.File)
        .WithOne()
        .OnDelete(DeleteBehavior.Cascade);
    modelBuilder.Entity<Content>()
        .HasOne(cn => cn.UseCase)
        .WithOne()
        .OnDelete(DeleteBehavior.Cascade);

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

Переменная содержимого

База данных - Результат

Полученный параметр:

Полученный параметр

Это код, в котором возникает проблема:

[HttpPost]
public JsonResult Create([FromBody] ContentJson data)
{
    List<Content> contents = new List<Content>();
    var contentName = string.Empty;
    var array = data.content;
    int order;

    for (int i = 0; i < array.Count; i++)
    {
        var files = JsonConvert.DeserializeObject<string[]>(array[i][1].ToString());

        if (files == null || files.Length == 0)
            continue;

        contentName = array[i][0].ToString();
        order = 1;

        foreach(var fileName in files)
        {
            Content content = new Content();    
            content.Order = order;
            content.UseCaseId = long.Parse(contentName);
            content.FileId = unitOfWork.FileRepository.Get(f => f.FileName.Equals(fileName)).First().FileId;
            contents.Add(content);
            order++;
        }
    }

    unitOfWork.ContentRepository.AddRange(contents);
    unitOfWork.Save();

    return Json(Ok());
}
  • ContentId генерируется автоматически.
  • EntityFramework и Do tnet в последней версии
  • I я уже пытался сэкономить на каждой итерации.
  • Пытался реализовать Equals и HashCode,

    public void Save()
    {
        context.SaveChanges();
    }
    
    private bool disposed = false;
    
    protected virtual void Dispose(bool disposing)
    {
        if (!disposed)
        {
            if (disposing)
            {
                context.Dispose();
            }
        }
        disposed = true;
    }
    
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    
    
    
    public Repository<Content> ContentRepository
    {
        get
        {
            if(contentRepository == null)
            {
                contentRepository = new Repository<Content>(context);
            }
            return contentRepository;
        }
    }
    

Кто-нибудь может мне помочь, пожалуйста? Я застрял в этой проблеме.

Ответы [ 2 ]

1 голос
/ 21 января 2020

У вас конфликтующая конфигурация FK.

IsUnique(false) здесь

modelBuilder.Entity<Content>()
    .HasIndex(ct => ct.FileId)
    .IsUnique(false);

modelBuilder.Entity<Content>()
    .HasIndex(ct => ct.UseCaseId)
    .IsUnique(false);

подразумевает, что FK не являются уникальными, но тогда WithOne() здесь

modelBuilder.Entity<Content>()
    .HasOne(cn => cn.File)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Content>()
    .HasOne(cn => cn.UseCase)
    .WithOne()
    .OnDelete(DeleteBehavior.Cascade);

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

Поскольку вы хотите, чтобы они не были уникальными, вы должны изменить отношения, чтобы они были один-ко-многим (или многие-к-одному) в зависимости от того, на какую сторону вы смотрите), заменив в обоих местах WithOne() на WithMany().

Как только вы это сделаете, вы можете удалить обе конфигурации HasIndex, поскольку они будут автоматически созданы для вас EF Основные соглашения. На самом деле они были бы созданы с вашей беглой конфигурацией, но как уникальные. Возможно, это то, что вы пытались исправить с помощью этих HasIndex утверждений, но это просто неправильное место, и вместо этого вы должны исправить причину.

0 голосов
/ 21 января 2020

Вместо contentName используйте fileName.contentName
т.е. content.UseCaseId = long.Parse (fileName.contentName); и то же самое относится к fileId

...