Question:
How can I dynamically generate SQL INSERT
and UPDATE
queries in a generic repository using Dapper? Currently, I'm hardcoding the property names in the SQL queries, but I want to make this dynamic so that it works for any entity. For example:
public async Task<int> AddAsync(T entity)
{
using (IDbConnection dbConnection = new NpgsqlConnection(_connectionString))
{
dbConnection.Open();
// How to dynamically generate "INSERT INTO TableName (Property1, Property2) VALUES (@Property1, @Property2)"?
return await dbConnection.ExecuteAsync($"INSERT INTO {typeof(T).Name} VALUES (@Property1, @Property2, ...)", entity);
}
}
Is there a way to use reflection or another approach to dynamically map the entity properties to the SQL query?
Question:
How can I dynamically generate SQL INSERT
and UPDATE
queries in a generic repository using Dapper? Currently, I'm hardcoding the property names in the SQL queries, but I want to make this dynamic so that it works for any entity. For example:
public async Task<int> AddAsync(T entity)
{
using (IDbConnection dbConnection = new NpgsqlConnection(_connectionString))
{
dbConnection.Open();
// How to dynamically generate "INSERT INTO TableName (Property1, Property2) VALUES (@Property1, @Property2)"?
return await dbConnection.ExecuteAsync($"INSERT INTO {typeof(T).Name} VALUES (@Property1, @Property2, ...)", entity);
}
}
Is there a way to use reflection or another approach to dynamically map the entity properties to the SQL query?
Share Improve this question edited Mar 17 at 7:56 Panagiotis Kanavos 132k16 gold badges203 silver badges265 bronze badges asked Mar 17 at 7:51 Abhi Kumar PrinceAbhi Kumar Prince 11 silver badge1 bronze badge 2 |1 Answer
Reset to default 2The Dapper.Contrib project already contains such methods. The list of available extension methods is:
T Get<T>(id);
IEnumerable<T> GetAll<T>();
int Insert<T>(T obj);
int Insert<T>(Enumerable<T> list);
bool Update<T>(T obj);
bool Update<T>(Enumerable<T> list);
bool Delete<T>(T obj);
bool Delete<T>(Enumerable<T> list);
bool DeleteAll<T>();
This allows using code like this:
connection.Insert(new Car { Name = "Volvo" });
It's not enough to use Reflection to construct the query. On one hand, reflection has a cost. If you use GetProperties
on every call you'll pay that cost over and over again. On the other hand, some properties require special handling, like auto-generated keys and computed columns
Dapper avoids both issues by caching both the type metadata and the key/computed column metadata. If you check the actual implementation of Insert you'll see code like this :
var name = GetTableName(type);
var allProperties = TypePropertiesCache(type);
var keyProperties = KeyPropertiesCache(type);
var computedProperties = ComputedPropertiesCache(type);
var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList();
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744574627a4581661.html
connection.Insert(new Car { Name = "Volvo" });
. If you want something more .... why not use a full featured ORM like EF Core? – Panagiotis Kanavos Commented Mar 17 at 7:57