.net 如何通过列值创建类示例?

6tqwzwtp  于 2023-02-14  发布在  .NET
关注(0)|答案(2)|浏览(103)

如何用Dapper通过特定的列值示例化类?
假设我们有一个包含列的表'items':ID、类型、名称...
并且,当Type等于“Burger”时,类Burger应该被示例化,当Type等于“Sandwich”时,类Sandwich应该被示例化.
我想到的第一个方法是对每种类型执行查询,例如:

var sandwiches = conn.Query<Sandwich>("SELECT * FROM items WHERE Type = 'Sandwich'");
var burgers = conn.Query<Burger>("SELECT * FROM items WHERE Type = 'Burger'");

但这种方法是昂贵的,因为我们将有尽可能多的查询项目类型的数量。我们可以做同样的工作与单一查询?(选择所有行和创建示例的基础上列值)

cunj1qz1

cunj1qz11#

一个类可以有一个泛型方法来做你想做的事情:

public class Query
{
    public IEnumerable<T> GenericQuery<T>(string query) 
    {
        using (SqlConnection cnn = new SqlConnection("Data Source=(LOCAL);Initial Catalog=LinqPadTest;Integrated Security=True;"))
        {
            cnn.Open();
            return cnn.Query<T>(query);
        }
    }
}

现在你可以这样称呼它

void Main()
{
    var q = new Query();
    var sandwiches = q.GenericQuery<Sandwich>("SELECT * FROM items WHERE Type = 'Sandwich'");
    var burgers = q.GenericQuery<Burger>("SELECT * FROM items WHERE Type = 'Burger'");
}
2jcobegt

2jcobegt2#

使用方法的泛型参数获取类型

public class ItemsRepository
{
    private const string Query = "SELECT * FROM items WHERE Type = @Type";
    public async Task<IEnumerable<T>> GetItemsBasedOnTypeAsync<T>()
    {
        await using var connection = new SqlConnection("Data Source=(LOCAL);Initial Catalog=LinqPadTest;Integrated Security=True;");
        await connection.OpenAsync();
        var parameters = new { Type = nameof(T) };
        return connection.Query<T>(Query, parameters);
    }
}

现在可以为任何项类型调用方法

var itemsRepository = new ItemsRepository();
var sandwiches = await itemsRepository.GetItemsBasedOnTypeAsync<Sandwich>();
var burgers = await itemsRepository.GetItemsBasedOnTypeAsync<Burger>();

V2(选择所有项目):use可以执行类似这样的操作,或者强制转换为基接口(如果存在)。

public class Item
{
    public int Id { get; set; }
    public string Type { get; set; }
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

public class Sandwich
{
    public Sandwich(Item item)
    {
        Id = item.Id;
        Property1 = item.Property1;
        Property2 = item.Property2;
    }
    public int Id { get; set; }
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

public class Burger
{
    public Burger(Item item)
    {
        Id = item.Id;
        Property1 = item.Property1;
        Property2 = item.Property2;
    }
    public int Id { get; set; }
    public int Property1 { get; set; }
    public int Property2 { get; set; }
}

public class ItemsRepository
{
    private const string Query = "SELECT * FROM items";
    public async Task<IEnumerable<object>> GetItemsBasedOnTypeAsync()
    {
        await using var connection = new SqlConnection("Data Source=(LOCAL);Initial Catalog=LinqPadTest;Integrated Security=True;");
        await connection.OpenAsync();
        var items =  connection.Query<Item>(Query);
        var objects = items.Select(Create)
            .ToList();
        return objects;
    }

    private object? Create(Item item) =>
        Assembly
            .GetExecutingAssembly()
            .CreateInstance(item.Type,true,BindingFlags.Public,null,
                new object[]{item},
                CultureInfo.DefaultThreadCurrentCulture, null);
}

相关问题