Как это сделать в LINQ или EF.Core?

#c# #linq #entity-framework-core

#c# #linq #entity-framework-core

Вопрос:

Предположим, у меня есть приложение с 3 моделями (class). Все модели имеют некоторый тип взаимосвязи, как показано ниже:

Пользователь -> Группа -> База данных

Лучшее объяснение:

  • User: класс, в котором хранятся имя пользователя, пароль и т.д., А также каждая группа, к которой принадлежит пользователь… Итак, у одного пользователя может быть одна или более групп.
  • Группа: укажите только название группы и базу данных, к которой имеет доступ эта группа. Группа может иметь одну или несколько баз данных и одного или нескольких пользователей.
  • База данных: сохраняет свойство подключения к базе данных.

Преобразуя это в class, может быть, это что-то вроде этого:

 class User {
  public int Id { get; set; }
  public string Username { get; set; }
  public string Password { get; set; }
  public List<Group> Groups { get; set; }
}

class Group {
  public int Id { get; set; }  
  public string Name { get; set; }
  public List<User> Users { get; set; } /* inverse */
  public List<Database> Databases { get; set; }
}

class Database {
  public int Id { get; set; }
  public string Hostname { get; set; }
  public string Username { get; set; }
  public string Password { get; set; }
  public string DbName { get; set; }
  public List<Group> Groups { get; set; } /* inverse */
}
  

Итак, теперь настоящая проблема.

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

Возможно ли сделать это в LINQ «прямым» способом? Или с помощью EF.Ядро (опять же, «прямым» способом)?

Или лучше более «длинный» способ, как я описал выше?

 var user = _context.user.code_to_get_user_by_id(id);
var groups = _context.user.code_to_get_all_groups();
var databases = groups.code_to_get_all_databases();

foreach (var group in groups) {
  // do something
}
  

Это всего лишь простой пример. В моем реальном приложении есть класс 4, с некоторыми другими отношениями и гораздо большим количеством свойств.

Ответ №1:

MSDN перечисляемый.Выберите множество примеров

 class PetOwner
{
    public string Name { get; set; }
    public List<String> Pets { get; set; }
}

public static void SelectManyEx1()
{
    PetOwner[] petOwners = 
        { new PetOwner { Name="Higa, Sidney", 
              Pets = new List<string>{ "Scruffy", "Sam" } },
          new PetOwner { Name="Ashkenazi, Ronen", 
              Pets = new List<string>{ "Walker", "Sugar" } },
          new PetOwner { Name="Price, Vernette", 
              Pets = new List<string>{ "Scratches", "Diesel" } } };

    // Query using SelectMany().
    IEnumerable<string> query1 = petOwners.SelectMany(petOwner => petOwner.Pets);

    Console.WriteLine("Using SelectMany():");

    // Only one foreach loop is required to iterate 
    // through the results since it is a
    // one-dimensional collection.
    foreach (string pet in query1)
    {
        Console.WriteLine(pet);
    }

    // This code shows how to use Select() 
    // instead of SelectMany().
    IEnumerable<List<String>> query2 =
        petOwners.Select(petOwner => petOwner.Pets);

    Console.WriteLine("nUsing Select():");

    // Notice that two foreach loops are required to 
    // iterate through the results
    // because the query returns a collection of arrays.
    foreach (List<String> petList in query2)
    {
        foreach (string pet in petList)
        {
            Console.WriteLine(pet);
        }
        Console.WriteLine();
    }
}

/*
 This code produces the following output:

 Using SelectMany():
 Scruffy
 Sam
 Walker
 Sugar
 Scratches
 Diesel

 Using Select():
 Scruffy
 Sam

 Walker
 Sugar

 Scratches
 Diesel
*/
  

DotNetPearls выбирает множество примеров

 using System;
using System.Linq;

class Program
{
  static void Main()
  {
    // Input.
    string[] array =
    {
    "dot",
    "net",
    "perls"
    };

    // Convert each string in the string array to a character array.
    // ... Then combine those character arrays into one.
    var result = array.SelectMany(element => element.ToCharArray());

    // Display letters.
    foreach (char letter in result)
    {
    Console.WriteLine(letter);
    }
  }
}

/* 
Output:

d
o 
t 
n 
e 
t 
p 
e 
r 
l 
s

*/
  

Вы можете использовать LINQ SelectMany функцию. Проверьте эти ссылки.

MSDN выбирает множество

Примеры DotNetPearls

Комментарии:

1. Добро пожаловать в Stack Overflow! Ответы только по ссылкам не рекомендуются и, вероятно, будут удалены в процессе проверки. Это потому, что рано или поздно ссылки разорвутся, что сделает ответ бесполезным. Попробуйте написать какой-нибудь код, который отвечает на вопрос.

2. например, после получения вашего пользователя, var userDBs = user.Groups.SelectMany(y => y.Databases)

3. устранено с помощью следующего кода: var bds = users.Where(u => u.Id == 1).SelectMany(g => g.Groups).SelectMany(d => d.Databases).GroupBy(d => d.Id).ToList();