我试图用Slapper.AutoMapper一起Dapper完成这样的事情:我怎样写一对多查询中Dapper.Net?.
我的POCO是这样的:
public class MyEntity
{
public string Name { get; set; }
public string Description { get; set; }
public int Level { get; set; }
public IList<int> Types { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我返回的数据库行是这样的:
因此,一个实体可以有多种类型.这就是我绘制内容的方式:
dynamic test = conn.Query<dynamic>(sql); Slapper.AutoMapper.Configuration.AddIdentifier(typeof(MyEntity), "Name");
var testContact = Slapper.AutoMapper.MapDynamic<MyEntity>(test);
Run Code Online (Sandbox Code Playgroud)
但是在我的所有结果对象中,Types属性为null.如何将所有Type值映射到IList类型?
我不确定是否有办法支持这一点,但我无法让 Dapper 将字符串参数值映射到 Postgresql citext 数据类型,因为它似乎正在使用文本类型。
特别是,我试图调用一个接受 citext 参数的函数 - 我得到的错误是:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param = new
{
schemaName = schema,
tableName = table
};
string insecureSalt = c.QueryMultiple(sql, param).Read<string>().FirstOrDefault();
ConnectionManager<T>.Close(c);
Error: Npgsql.PostgresException: 42883: function dbo.MyFunction(text, text) does not exist.
Run Code Online (Sandbox Code Playgroud)
匹配的签名是 function dbo.MyFunction(citext, citext) 很明显它无法使用默认映射找到它。
根据 Npgsql - http://www.npgsql.org/doc/types.html我需要能够将 NpgsqlDbType.Citext 指定为类型,但我找不到使用 Dapper 执行此操作的方法。
解决了由于这里离吉文回答,完整的解决方案:
var c = ConnectionManager<T>.Open();
string sql = @"select * from ""dbo"".""MyFunction""(@schemaName, @tableName);";
var param …Run Code Online (Sandbox Code Playgroud) 据我所知,Object.GetType()永远不应该返回null.(相关讨论)
Dapper .Query()返回要被视为动态对象的私有类DapperRow实例.我发现了一件奇怪的事:DapperRow的.GetType()返回null.
这是重现问题的示例代码.创建一个C#项目,引用Dapper并打开与SQL Server(或其他数据库)的连接,使用.Query()执行简单的select查询并检索第一行结果.使用GetType()获取结果对象的类型,返回值为null.
using (SqlConnection cn = new SqlConnection(csSql))
{
var rec = cn.Query("select getdate() as D").Single();
var t = rec.GetType(); // t == null
Console.WriteLine(t.Name); // null reference exception
}
Run Code Online (Sandbox Code Playgroud)
我怀疑动态或私有类型是null的原因,所以我编写我的类库进行测试:
namespace Lib
{
public class Blah
{
public static dynamic SecretObject;
static Blah()
{
SecretObject = new PrivateType();
}
}
class PrivateType
{
}
}
Run Code Online (Sandbox Code Playgroud)
在另一个项目中,获取动态类型静态字段并调用GetType():
dynamic obj = Lib.Blah.SecretObject;
Console.WriteLine(obj.GetType().Name); // "Lib.PrivateType"
Run Code Online (Sandbox Code Playgroud)
根据测试结果,即使将私有类型转换为动态,我仍然可以从GetType()获取私有类型信息,为什么DapperRow.GetType()返回null?
我们将基于Dapper的应用程序移植到.NET Core,我们的事务代码存在问题.
我们使用"动作"来执行东西
public Action<IDbConnection> CreateAction(string statement, object values)
{
return (dbConnection) => dbConnection.Execute(statement, values);
}
Run Code Online (Sandbox Code Playgroud)
我们使用方法来执行这些操作
public void Execute(IEnumerable<Action<IDbConnection>> actions)
{
using (IDbConnection connection = OpenConnection())
using (IDbTransaction transaction = connection.BeginTransaction())
{
try
{
foreach (var action in actions)
{
action(transaction.Connection);
}
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于.NET Framework和Dapper 1.42,但在使用Dapper 1.50.2的.NET Core上失败.
System.InvalidOperationException:'ExecuteNonQuery要求命令在分配给命令的连接处于挂起的本地事务中时具有事务.该命令的Transaction属性尚未初始化.
如果我们使用它删除交易也可以.
需要改变什么来使它工作?
我有一张表,我将字典作为 json 存储在一列中。在将内容保存到/从数据库加载/加载内容时,如果可能,我希望能够使 json 反/序列化不可见。是否可以在不使用包含 json 表示的 Foo 中的另一个属性的情况下以某种方式使用 dapper 来做到这一点?
// where someData is the dictionary column
void Save(IDbConnection conn, Foo foo){
conn.Execute("INSERT INTO foos (name, <othercols...>, someData) VALUES (@Name, <othercols...>, @SomeData, foo);
}
Run Code Online (Sandbox Code Playgroud)
我可以手动将 Foo 映射到一个新的动态对象中,但是因为有其他列会很乏味,所以我想知道是否还有其他方法?
我试图弄清楚如何在交易中正确使用 Dapper。但我仍然认为我做错了什么。我发现的所有示例都没有使用异步。
有人可以建议我如何正确地做吗?
class DapperAsyncTransaction
{
private readonly IDbConnection _dbConnection;
private IDbTransaction _dbTransaction;
private IDbConnection Connection => _dbTransaction.Connection;
/// <summary>
/// Constructor
/// </summary>
/// <param name="dbConnection"></param>
public DapperAsyncTransaction(
IDbConnection dbConnection)
{
_dbConnection = dbConnection;
_dbConnection.Open();
_dbTransaction = _dbConnection.BeginTransaction();
}
public async Task Execute()
{
try
{
await Connection.ExecuteAsync(
@"insert into Persons(Name, Surname) values" +
"(@Name, @Surname)",
param: new { Name = "John", Surname = "Doe" },
transaction: _dbTransaction);
_dbTransaction.Commit();
}
catch (Exception)
{
_dbTransaction.Rollback();
}
finally
{
_dbTransaction.Dispose();
_dbTransaction …Run Code Online (Sandbox Code Playgroud) 一个IDbContext有一个DatabaseFacade,它有一个CurrentTransaction属性。但是CurrentTransaction是一个IDbContextTransaction。我想将其传递IDbTransaction给Dapper。
如何获得IDbTransaction而不是IDbContextTransaction?
我正在寻找一种方法来仅更新 Dapper 中的设置属性。即仅当实体的属性不为空时才更新实体的属性。
我正在用一种相当粗糙的方法解决同样的问题,如下所示,但我相信应该有一种更简洁的方法来做到这一点。
public void UpdateCustomer(Customer cust)
{
try
{
StringBuilder sb = new StringBuilder("UPDATE CUSTOMER_SETUP SET DATE_MODIFIED = @DATE_MODIFIED ");
if(cust.BUSINESSNAME != null) sb.Append(",BUSINESSNAME = @BUSINESSNAME ");
if (cust.BUSINESS_ADDRESS != null) sb.Append(",BUSINESS_ADDRESS = @BUSINESS_ADDRESS ");
if (cust.CONTACT_NAME != null) sb.Append(",CONTACT_NAME = @CONTACT_NAME ");
if (cust.CONTACT_TITLE != null) sb.Append(",CONTACT_TITLE = @CONTACT_TITLE ");
if (cust.CONTACT_PHONE1 != null) sb.Append(",CONTACT_PHONE1 = @CONTACT_PHONE1 ");
if (cust.CONTACT_PHONE2 != null) sb.Append(",CONTACT_PHONE2 = @CONTACT_PHONE2 ");
if (cust.CONTACT_EMAIL != null) sb.Append(",CONTACT_EMAIL = @CONTACT_EMAIL ");
if (cust.CONTACT_URL != …Run Code Online (Sandbox Code Playgroud) 我在 Postgres 中使用 Dapper,我想记录一些诊断信息,尤其是正在运行的实际查询。
如果我使用的是 SQL Server,我会这样做
let connection = new SqlConnection(connectionString)
connection.StatisticsEnabled = true
// run query
let stats = connection.RetrieveStatistics()
Run Code Online (Sandbox Code Playgroud)
但我似乎找不到类似的东西NpgsqlConnection。
检索正在运行的实际查询的最佳方法是NpgsqlConnection什么?
此资源解释了如何Computed排除属性(仅在更新中?)。
指定应从更新中排除该属性。
Run Code Online (Sandbox Code Playgroud)[Table("Invoice")] public class InvoiceContrib { [Key] public int InvoiceID { get; set; } public string Code { get; set; } public InvoiceKind Kind { get; set; } [Write(false)] [Computed] public string FakeProperty { get; set; } } using (var connection = My.ConnectionFactory()) { connection.Open(); var invoices = connection.GetAll<InvoiceContrib>().ToList(); // The FakeProperty is skipped invoices.ForEach(x => x.FakeProperty += "z"); var isSuccess = connection.Update(invoices); }
不Write(false)达到同样的目的吗?[Computed]和 和有[Write(false)]什么区别?
编辑:
我刚刚检查了为回答我的问题而链接的资源。它几乎一针见血!有人可以确认这两个属性是否执行相同的操作,但只是以两种不同的方式表达,以便为用户提供更好的抽象?
dapper ×10
c# ×5
npgsql ×2
.net ×1
.net-core ×1
asynchronous ×1
attributes ×1
f# ×1
postgresql ×1
transactions ×1
types ×1