【问题标题】:How to insert an object into PostGreSql using Dapper Extensions without specifying primary key explicitly?如何在不明确指定主键的情况下使用 Dapper Extensions 将对象插入 PostGreSql?
【发布时间】: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

标签: c# postgresql dapper dapper-extensions


【解决方案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" });

【讨论】:

    猜你喜欢
    • 2010-12-16
    • 2016-09-21
    • 2019-11-30
    • 2016-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    相关资源
    最近更新 更多