Entity Framework позволяет избежать дублирования во многих отношениях - PullRequest
0 голосов
/ 12 апреля 2020

Я немного застрял с подходом, основанным на базе данных EF 6.

У меня есть 3 таблицы в SQL Сервер:

  • Участники
  • Команды
  • JT_Teams_Members (таблица соединений)

Я хотел бы вставить данные в эти отношения.

Из кода я получаю список команд, которые Я повторил

Вставка:

foreach (var team in teams.Teams)
{
    var teamEntity = new Contexts.Team
            {
                TeamName = team.Name,
                ....
            };

    foreach (var member in team.Members)
    {
        teamEntity.Members.Add(
                new Contexts.Member()
                {
                    MemberName = member.Name,
                    EmailAddress = member.Email,  
                ...
                });
    }

    DbUtility.Context.Teams.Add(teamEntity);
}

Моя проблема в том, что я нашел много дубликатов в таблице участников, что не так хорошо.

Как мне управлять вставить, чтобы избежать дублирования и перенаправить идентификаторы в правильное место?

1 Ответ

0 голосов
/ 13 апреля 2020

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

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

  1. Для всех связанных объектов всегда передавайте PK в ваших моделях представления. Для участников, если вы можете выбрать из существующих участников, даже если вы отображаете только имя и адрес электронной почты, передайте идентификатор участника в вашей модели представления для последующих поисков.

Оттуда мы можем начать чтобы посмотреть на что-то вроде ниже:

var memberIds = teams.Teams
    .SelectMany(t => t.Members)
    .Select(m => m.MemberId)
    .Where(m => m.MemberId != 0)
    .ToList();

var existingMembers = Context.Members
    .Where(m => memberIds.Contains(m.MemberId))
    .ToList();


foreach (var team in teams.Teams)
{
    var teamEntity = new Contexts.Team
    {
        TeamName = team.Name,
        ....
    };

    foreach (var member in team.Members)
    {   //We assume that all e-mail addresses are unique.
        var existingMember = existingMembers.SingleOrDefault(m => m.Email == member.Email);
        if (existingMember == null)
        {
            existingMember = new Member()
            {
                MemberName = member.Name,
                EmailAddress = member.Email,  
            ...
            });
            existingMembers.Add(existingMember); // For future reference.
        }
        teamEntity.Members.Add(existingMember);
    }

    DbUtility.Context.Teams.Add(teamEntity);
}

Первым шагом является поиск любых существующих членов для команд. Если вы знаете, что нет существующих членов, тогда вы можете пропустить эту загрузку и просто использовать изначально пустую коллекцию. Когда мы go через наши команды, мы сначала проверяем существующую коллекцию на наличие участника, соответствующего адресу электронной почты. Если мы найдем его, мы используем его, в противном случае мы создадим нового члена и добавим его в коллекцию. Таким образом, когда добавляется другая команда с таким же членом, она обнаруживается в коллекции и будет использоваться та же ссылка.

Когда EF вставляет данные, он учитывает ссылки, а не обязательно идентификаторы / ограничения, чтобы связать объекты с та же ссылка, а не создание дубликатов. Если у вас есть 2 объекта, которые ссылаются на одного и того же члена (joe. smith@gmail.com), то вы хотите убедиться, что оба объекта ссылаются на один и тот же элемент-член для joe.smith, а не на 2 разных объекта с одним и тем же адресом электронной почты. При работе с массовыми операциями (вставка большого количества команд) вы захотите сохранить локальный кеш или читать из DbContext, чтобы использовать его кеш. Для отдельных операций вы всегда должны go передавать DbContext, чтобы получить существующую сущность, если она доступна, прежде чем пытаться создать новую ссылку. (Во избежание дублирования данных или нарушений ограничений / исключений дубликатов ключей.)

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