C # .NET Core - Dapper - Multi-Join-Mapping (все отдельные [A] с соответствующими [B]) - PullRequest
0 голосов
/ 17 октября 2019

Я относительно молодой в .NET Core и совершенно новый в использовании Dapper. Но у меня есть некоторые навыки в C # (1-2 года) . Мой первый проект мне нужно начать с dapper и отображения там.

SQL-таблицы:

SQL-Tables

таблица [A] содержание:

    id:                                     name:
    ---                                     -----
    F3613B62-EEB5-4B27-9A20-4038F60B25BD    name-01-of-a
    6A68ED79-5605-43B4-9F70-675CAF3C5C65    name-02-of-a
    76CB90D6-93BE-452E-8A72-F525180B77E8    name-03-of-a

таблица [AB] содержание:

    A_id:                                   B_id:
    -----                                   -----
    F3613B62-EEB5-4B27-9A20-4038F60B25BD    19C592B1-4D4C-4660-9D1D-C5C4AA1F296C
    F3613B62-EEB5-4B27-9A20-4038F60B25BD    C71E6490-2410-4FA3-A4D0-F24B8207B67A
    6A68ED79-5605-43B4-9F70-675CAF3C5C65    D763F490-A6B6-4FCB-A3BA-755A44E16D6F
    6A68ED79-5605-43B4-9F70-675CAF3C5C65    19C592B1-4D4C-4660-9D1D-C5C4AA1F296C
    76CB90D6-93BE-452E-8A72-F525180B77E8    D763F490-A6B6-4FCB-A3BA-755A44E16D6F
    76CB90D6-93BE-452E-8A72-F525180B77E8    19C592B1-4D4C-4660-9D1D-C5C4AA1F296C
    76CB90D6-93BE-452E-8A72-F525180B77E8    C71E6490-2410-4FA3-A4D0-F24B8207B67A

таблица [B] содержание:

    id:                                     name:
    ---                                     -----
    19C592B1-4D4C-4660-9D1D-C5C4AA1F296C    name-01-of-b
    C71E6490-2410-4FA3-A4D0-F24B8207B67A    name-02-of-b
    D763F490-A6B6-4FCB-A3BA-755A44E16D6F    name-03-of-b

Объект:

public class AEntity
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public IEnumerable<AEntity> A { get; set; } = null;
}

ЗИМА:

public class B
{
  public Guid Id { get; set; }
  public string Name { get; set; }
}

Одиночный запрос на присоединение:

public async Task<AEntity> GetById(Guid id)
{
  using (var connection = Connection)
  {
    var list = new List<BEntity>();
    return (await connection.QueryAsync<AEntity, BEntity, AEntity>(
      sql: $"SELECT a.*, b.* FROM ab INNER JOIN a ON a.id = ab.a_id INNER JOIN b ON b.id = ab.b_id WHERE a.id=@id",
      map: (a, b) => {
        list.Add(b);
        a.B = list;
        return a;
      },
      param: new {
        id
      }
    )).AsQueryable().FirstOrDefault();
  }
}

Это действительно просто. Существует таблица реализаций [AB] , таблица [A] и другая таблица [B] . (Например, таблица [A] может быть [ФИЛЬМЫ] , а таблица [B] может быть [ACTORS] ) Так один актер играет в нескольких фильмах. Но также несколько актеров играют в одном фильме. ( n: n )

GetById (одна сущность) работает, но мне нужен GetAll (все сущности) как IEnumerableколлекция ... Это должно быть то же отображение: содержимое [B] как совокупность всех (3) [A] в соответствующем поле IEnumberable [A] объект. Чтобы мы получили три [A] объекта:

желаемый tupel / объект:

[
  {
    "id": "F3613B62-EEB5-4B27-9A20-4038F60B25BD",
    "name": "name-01-of-a",
    "b": [
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      },
      {
        "id": "C71E6490-2410-4FA3-A4D0-F24B8207B67A",
        "name": "name-02-of-b"
      }
    ]
  },
  {
    "id": "6A68ED79-5605-43B4-9F70-675CAF3C5C65",
    "name": "name-02-of-a",
    "b": [
      {
        "id": "D763F490-A6B6-4FCB-A3BA-755A44E16D6F",
        "name": "name-03-of-b"
      },
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      }
    ]
  },
  {
    "id": "76CB90D6-93BE-452E-8A72-F525180B77E8",
    "name": "name-03-of-a",
    "b": [
      {
        "id": "D763F490-A6B6-4FCB-A3BA-755A44E16D6F",
        "name": "name-03-of-b"
      },
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      },
      {
        "id": "C71E6490-2410-4FA3-A4D0-F24B8207B67A",
        "name": "name-02-of-b"
      }
    ]
  }
]

All-Join-Request:

public async Task<IEnumerable<AEntity>> GetById(Guid id)
{
  using (var connection = Connection)
  {
    var list = new List<BEntity>();
    var aId = new Guid();
    return (await connection.QueryAsync<AEntity, BEntity, AEntity>(
      sql: $"SELECT a.*, b.* FROM ab INNER JOIN a ON a.id = ab.a_id INNER JOIN b ON b.id = ab.b_id",
      map: (a, b) => {
        if (aId != a.Id)
        {
          aId = a.Id;
          list.Clear();                    
        }
        list.Add(b);
        a.B = list;
        return a;
      },
      param: new {
        id
      }
    )).AsQueryable();
  }
}

Но это не работает. :( Я получаю 7x [A] с каждым 3x [B] .: /Спасибо за каждую помощь. :)

1 Ответ

0 голосов
/ 18 октября 2019

Объект:

public class AEntity
{
  public Guid Id { get; set; }
  public string Name { get; set; }
  public ISet<AEntity> A { get; set; } = null;
}

Одиночный запрос на присоединение:

public async Task<AEntity> GetById(Guid id)
{
  using (var connection = Connection)
  {
    var as= new Dictionary<Guid, BEntity>();
    return (await connection.QueryAsync<AEntity, BEntity, AEntity>(
      sql: $"SELECT a.*, b.* FROM ab INNER JOIN a ON a.id = ab.a_id INNER JOIN b ON b.id = ab.b_id WHERE a.id=@id",
      map: (a, b) => {
        if (!as.TryGetValue(a.Id, out var entity))
        {
          entity = a;
          entity.B= new HashSet<b>();
          as.Add(a.Id, entity);
        }
        entity.B.Add(b);
        return entity;
      },
      param: new {
        id
      }
    )).FirstOrDefault();
  }
}

All-Join-Request:

public async Task<IEnumerable<AEntity>> GetById(Guid id)
{
  using (var connection = Connection)
  {
    var as= new Dictionary<Guid, BEntity>();
    return (await connection.QueryAsync<AEntity, BEntity, AEntity>(
      sql: $"SELECT a.*, b.* FROM ab INNER JOIN a ON a.id = ab.a_id INNER JOIN b ON b.id = ab.b_id",
      map: (a, b) => {
        if (!as.TryGetValue(a.Id, out var entity))
        {
          entity = a;
          entity.B= new HashSet<b>();
          as.Add(a.Id, entity);
        }
        entity.B.Add(b);
        return entity;
      },
      param: new {
        id
      }
    )).Distinct();
  }
}

(All-Join-Request) возвратил tupel / объект:

[
  {
    "id": "F3613B62-EEB5-4B27-9A20-4038F60B25BD",
    "name": "name-01-of-a",
    "b": [
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      },
      {
        "id": "C71E6490-2410-4FA3-A4D0-F24B8207B67A",
        "name": "name-02-of-b"
      }
    ]
  },
  {
    "id": "6A68ED79-5605-43B4-9F70-675CAF3C5C65",
    "name": "name-02-of-a",
    "b": [
      {
        "id": "D763F490-A6B6-4FCB-A3BA-755A44E16D6F",
        "name": "name-03-of-b"
      },
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      }
    ]
  },
  {
    "id": "76CB90D6-93BE-452E-8A72-F525180B77E8",
    "name": "name-03-of-a",
    "b": [
      {
        "id": "D763F490-A6B6-4FCB-A3BA-755A44E16D6F",
        "name": "name-03-of-b"
      },
      {
        "id": "19C592B1-4D4C-4660-9D1D-C5C4AA1F296C",
        "name": "name-01-of-b"
      },
      {
        "id": "C71E6490-2410-4FA3-A4D0-F24B8207B67A",
        "name": "name-02-of-b"
      }
    ]
  }
]

Теперь все работает нормально. Я просто использовал простой словарь-помощник , чтобы буферизовать отдельные B в правильном As. И я изменил IEnumerable на ISet (HashSet), потому что .Add () - Метод. :)

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

...