如何使用查询返回另一个模型?

时间:2019-11-08 05:39:17

标签: c# sqlite dapper

我有以下数据库表:

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 个答案:

答案 0 :(得分:1)

从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
            }
        };
}

答案 1 :(得分:0)

这是我最终使用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
        }
    };
}

答案 2 :(得分:0)

这是一个简单的一对一映射,如下所示:

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");
}

您告诉查询获取UserPet并返回一个用户。划分UserPet的数据库列为“ pet_name”,这意味着“ pet_name”左侧的所有列都映射到用户,“ pet_name”右侧的列(包括pet_name)被映射。被映射到宠物。结合这两种方法由您决定。