2016-06-23 2 views
6

Я пытаюсь сопоставить отношения N-N с dapper, используя DB MySQL. Это более или менее код.Dapper multi mapping many to many relationship

 var query = new StringBuilder(); 
     query.Append("SELECT O.Id, O.Email, O.Status, P.Name FROM Owners AS O"); 
     query.Append(" INNER JOIN OwnerPets OP ON OP.OwnerId = O.Id"); 
     query.Append(" INNER JOIN Pets AS P ON P.Id = OP.PetId"); 
     query.Append(" WHERE O.Status = @Status;"); 

     using (var dbConnection = CreateConnection()) 
     { 
      return dbConnection.Query<Owner, IEnumerable<Pet>, Owner>(query.ToString(), (owner, pets) => 
      { 
       owner.Pets = pets.ToList(); 
       return Owner; 
      }, new { Status = status }, splitOn: "OwnerId, PetId"); 
     } 

Запроса отлично работает в клиенте SQL, но когда я запускаю код выше, я получаю это исключение: «. При использовании API-интерфейсов многоканальных отображений убедитесь, что вы установите splitOn параметры, если у вас есть другие, чем Id ключи параметр name: splitOn "

Возможно ли сопоставить отношение NN с промежуточной таблицей (OwnerPets)? ... Если так ... что я делаю неправильно?

ответ

5

Я не уверен, что вы можете заставить Dapper возвращать данные напрямую, как вы хотите, но вы можете загрузить данные так, чтобы между Владельцами и Домашними животными была взаимно-однозначная взаимосвязь, а затем следовать ей с запросом LINQ для группировки домашних животных для каждого владельца.

return dbConnection 
    .Query<Owner, Pet, Owner>(
     query, 
     (owner, pet) => 
     { 
      owner.Pets = owner.Pets ?? new List<Pet>(); 
      owner.Pets.Add(pet); 
      return owner; 
     }, 
     new { Status = status }, 
     splitOn: "Name" 
    ) 
    .GroupBy(o => o.Id) 
    .Select(group => 
    { 
     var combinedOwner = group.First(); 
     combinedOwner.Pets = group.Select(owner => owner.Pets.Single()).ToList(); 
     return combinedOwner; 
    });