如何在不明确指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?

Posted

技术标签:

【中文标题】如何在不明确指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?【英文标题】:How to insert an object into PostGreSql using Dapper Extensions without specifying primary key explicitly? 【发布时间】:2019-07-24 13:46:16 【问题描述】:

当我想在我的数据库中插入一个对象时,我收到一个错误:

对象引用未设置为对象的实例

当对象的主键字段是null 时。当我为该字段设置一些值时,它工作正常。

我的表创建:

create table Appointment
(
    AppointmentUUID uuid DEFAULT uuid_generate_v4 () primary key,
;

我的班级:

public class Appointment 

    public Guid? AppointmentUUID  get; set; 
    public void Insert(NpgsqlConnection conn)
    
        var i = conn.Insert(this);            
    

我的电话号码:

var lConnection = new NpgsqlConnection(connstring);
lConnection.Open();

var a = Appointment.Get2(allAppoints.FirstOrDefault().AppointmentUUID.Value, lConnection);
var newApp = new Appointment();
newApp.Insert(lConnection);

肯定有一种方法可以插入一个对象并让数据库创建它自己的Guid。我错过了什么?

【问题讨论】:

为什么要服务器生成呢?为什么不用 C# 生成它? github.com/ericdc1/Dapper.SimpleCRUD 提到Insert<Guid,T>(entity) - Inserts a record and returns the new guid primary key 你试过吗? @mjwills 我的印象是,如果 Db 自己创建 PK,性能会更好?此外,感觉 PK 生成超出了 DAL 的范围;这是 Db 本身关心的问题 @RobertMcKee 我怀疑 generation 是问题 - 更多的问题是数据库是否以某种方式生成 GUID 以提高索引的性能等。 我将提倡在数据库中生成 PK,无论是串行还是 UUID,因为我认为不将其移动到客户端有一些很好的理由。在数据库上,无论行如何创建,适当的类型都是如此。无论该行是由应用程序生成的,还是由后来的应用程序生成的(并且数据结构化往往比应用程序寿命更长),或者是直接在数据库上快速修复的应用程序,都是如此。对于性能,客户端生成 UUID 需要多长时间。至于任何一种方式都相同的索引,总是在 DB 和选择的类型中。只是MHO 【参考方案1】:

两个更正:

首先,您不需要使AppointmentUUID 可以为空。所以只需删除它:

public Guid AppointmentUUID  get; set; 

其次,您可能需要将AppointmentUUID映射为Key

Map(x => x.AppointmentUUID).Key(KeyType.Guid);

这将告诉 Dapper Extensions 自己生成密钥 (Guid)。

Dapper Extensions 带有开箱即用的default mappings,它基于约定。但是,显然,您必须稍微扩展它以处理某些情况。映射很简单,不需要对每一列进行映射;只是特殊的列。

另请注意,您的密钥属性以“ID”结尾,类型为Guid。 Dapper Extensions 应该自动将其视为 Key 而无需映射。以防万一您的模型中还有其他以“ID”结尾的属性,这可能是问题所在。就个人而言,我总是更喜欢明确地映射;以防我将来添加一些东西;现有的东西不应该开始表现得很奇怪。

在你的情况下,映射可以像下面这样完成:

internal sealed class AppointmentMapper : ClassMapper<Appointment>

    public AppointmentMapper()
    
        Table("Appointment");
        Map(x => x.AppointmentUUID).Key(KeyType.Guid);//<--Just map this
        AutoMap();//<-- This will take care about all other columns you do not map explicitly; ofcouse based on conversions
    

然后,在项目启动时调用:

DapperExtensions.DapperExtensions.SetMappingAssemblies(new[]  "Your Assempby Here" );

【讨论】:

以上是关于如何在不明确指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?的主要内容,如果未能解决你的问题,请参考以下文章

在不使用主键或辅助键的情况下使用 azure 存储帐户进行身份验证

javascript 可以在不指定 PHP 等键的情况下将元素添加到数组吗?

Groovy - 如何在不更新地图的情况下使用默认值获取地图值

如何获取表的 PRIMARY KEY COLUMNS(在 COMPOSITE 主键的情况下)

如何在没有自动增量的情况下创建主键?

如何在不知道 json 键的情况下使用 JsonReader 从 json 读取值