Избегайте дублирования записей в Entity Framework, используя MSSQL и .Net Core - PullRequest
0 голосов
/ 02 ноября 2019

У меня есть 2 связанные таблицы, которые являются сборками и деталями.

Класс моей сборки:

public class Assembly{
  public int Id { get; set; }
  public string No{ get; set; }
  public string Name { get; set; }

  public int? ParentId { get; set; }
  public Assembly Parent { get; set; }

  public List<Assembly> Children { get; set}
  public List<Part> Parts { get; set; }
}

Класс моей детали:

public class Part{
   public int Id { get; set; }
   public string No { get; set; }
   public string Name { get; set; }
   public string Image { get; set; }

   public int AssemblyId { get; set;}
   public Assembly Assembly { get; set; }
}

Что яЯ сначала создаю сборки в контроллере. Затем, когда я создаю сборку, открывается страница загрузки файла, затем я загружаю файлы Excell и сопоставляю исключительные данные с моим объектом Part как ссылкой на мой объект Assembly. (Для каждой детали AssemblyId будет AssemblyId, полученный из маршрута)

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

Например, предположим, что есть деталь, деталь №: 555, Part Name: Axle.

И давайте предположим, что я собираюсь создать 5 Assembly в моем проекте. И каждая сборка будет иметь данные, импортированные из разных файлов исключений.

И каждый сборщик содержит одну и ту же деталь, которая имеет свою часть номер: 555 и имя детали: ось, но, очевидно, с другим AssemblyId (FK).

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

What I 'Я хотел бы добиться, чтобы избежать этой ситуации ...

Я не хочу повторять свои данные. На самом деле я думаю, что решение, но я не уверен, что это хорошее решение. Я мог бы сделать заявление "если" и проверить, загружая данные из Excell, если в базе данных существует Часть с этой информацией, я не могу загрузить этот конкретныйстрока в таблицу, и использовать часть, которая уже существует. Но я думаю, что это замедлит мой проект.

Надеюсь, я четко спросил ...

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Это проблема реляционного проектирования, ваша таблица деталей не должна иметь ссылку на таблицу сборки. Таблица сборки должна содержать ссылку только на идентификаторы деталей.

Обратите внимание:

  • Чтобы иметь одну таблицу для определения сборки, в этой таблице не должны быть задействованы детали, только сборки.
  • Чтобы иметь одну таблицу для отношения сборочных деталей.

public class Assembly_Part {public int AssemblyId {get;set;} public int PartId {get;установлен;}}

  • Чтобы таблица деталей не имела отношения к сборкам (удалите AssemblyId из таблицы деталей)

, если вы не хотите, чтобы некоторые детали были частьюдля конкретной сборки, то вы должны создать дополнительное отношение для id-сборок деталей.

Когда вы отправляете данные в БД, вы должны отправлять связанную сборку и идентификатор детали, а не определение детали.

Тогда процесс определения детали должен позаботиться о создании детали, а не о процессе создания сборки.

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

Это мой оптимальный сценарий:

  • Если вы хотите создать сборку, ваш процесс определит новый AssemblyId и позволит вам выбрать детали для включения в сборку. В БД вы будете добавлять только записи в таблицу сборки.

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

  • При загрузке деталей для сборки вы создадите список, который будет содержать все детали, относящиеся к текущему поиску, без дублирования.

См. Рекомендации по разработке базы данных .

0 голосов
/ 02 ноября 2019

Вы можете переопределить метод equals для любого класса, который вы просматриваете (в данном случае Part), и сравнить поля, которые вам нужны, чтобы увидеть, совпадает ли один Part с другим в контексте вашего приложения. Ниже приведен простой пример:

  public class Part 
  {
    public string Name { get; set; }

    public DateTime? InactiveDate { get; set; }

    public int AssemblyId {get; set;}

    public override bool Equals(object obj)
    {
      Part yVal = (Part) obj;

      if (yVal == null)
      {
        return false;
      }

      // compare each of the values we care about. i.e: NOT comparing AssemblyId
      return this.Name == yVal.Name
        && this.InactiveDate == yVal.InactiveDate;
    }

Затем вы будете использовать это, когда собираетесь сохранить новую деталь в базе данных, посмотреть, есть ли какая-либо существующая деталь .Equals какая-либо существующая Part:

var existingPart = db.Parts.SingleOrDefault(x => myPartToSave.Equals(x))

if(existingPart != null)
{
    myAssemblyToSave.Parts.Remove(myPartToSave);
    myAssemblyToSave.Parts.Add(existingPart);
}

//then save your part as you normally would

Если это так, сохраните Assembly, используя существующий Part, а если нет, сохраните Assembly и Part, как обычно.

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

Еще одно примечание: это также лучшая практикапереопределить метод GetHashCode при переопределении Equals. Я не буду вдаваться в подробности, почему, поскольку это выходит за рамки этого вопроса, вы сможете легко найти информацию по этому вопросу. Вот очень хорошая тема здесь на ТАК об этом

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