Как вернуть модель в другую, используя запрос? - PullRequest
0 голосов
/ 08 ноября 2019

У меня есть следующая таблица базы данных:

CREATE TABLE "users" (
    "id"    INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT UNIQUE,
    "email" TEXT NOT NULL,
    "pet_name"  TEXT NOT NULL,
    "pet_age"   INTEGER NOT NULL
);

У меня есть следующие модели C #:

public class User
{
    public string Email { get; set; }
    public Pet Pet { get; set; }
}

public class Pet
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Как я могу сделать запрос SQLite SELECT *, который бы возвратил User объект, с нужной Pet информацией?

Это то, что я пробовал:

public static User GetUserByEmail(string email)
{
    using var con = new SQLiteConnection(Globals.DbConnectionString);

    return con.QueryFirstOrDefault<User>($"SELECT * FROM users WHERE email = @email COLLATE NOCASE", new
    {
        email
    });
}

Но это не сработает с моделью Pet, очевидно, это не так. т магия.

Ответы [ 3 ]

1 голос
/ 08 ноября 2019

Поля, которые вы возвращаете из SQL, должны соответствовать вашей модели. Вы можете создать конкретный объект с вашим запросом возврата и затем проанализировать его с вашими реальными объектами:

public class UserPetQueryResult
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string PetName { get; set; }
    public int PetAge { get; set; }
}



public static User GetUserByEmail(string email)
{
    using var con = new SQLiteConnection(Globals.DbConnectionString);

     UserPetQueryResult  dbResult = con.QueryFirstOrDefault<UserPetQueryResult>($"SELECT id as Id,email as Email,pet_name as PetName,pet_age as PetAge FROM users WHERE email = @email COLLATE NOCASE", new
        {
            email
        });

    return new User() {
            Email = dbResult.Email,
            Pet = new Pet(){
                Name = dbResult.PetName,
                Age = dbResult.PetAge
            }
        };
}
0 голосов
/ 08 ноября 2019

Это простое взаимно-однозначное сопоставление, подобное этому:

string sql = "SELECT * FROM {DbTable} WHERE discord_id = @discordId";

using (var connection = new SQLiteConnection(Globals.DbConnectionString))
{
    connection.Open();

    var foundUser = connection.QueryFirstOrDefault<User, Pet, User>(
            sql,
            (user, pet) =>
            {
                user.Pet = pet;
                return user;
            },
            splitOn: "pet_name");
}

Вы указываете запросу получить User и Pet и возвращаете пользователя. Столбец базы данных, который разделяет User и Pet, имеет значение «имя_петь», что означает, что все столбцы слева от «имя_петь» отображаются для пользователя, а столбцы справа от «имя_петь» (включая имя_петь) сопоставляются с именем «пэт». ,Вам решать объединить эти два.

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

Это то, что я закончил с использованием dynamic:

public static User GetUser(ulong discordId)
{
    using var con = new SQLiteConnection(Globals.DbConnectionString);

    var user = con.QueryFirstOrDefault<dynamic>($"SELECT * FROM {DbTable} WHERE discord_id = @discordId", new
    {
        discordId
    });

    if (user == null) return null;

    return new User
    {
        DiscordId = (ulong)user.discord_id,
        RegistrationTimestamp = (long)user.registration_timestamp,
        Email = (string)user.email,
        Balance = (double)user.balance,
        Profit = new Profit
        {
            Net = (double)user.net_profit,
            ATH = (double)user.ath_profit,
            ATL = (double)user.atl_profit
        }
    };
}
...