1

这是查询:

string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint) 
                             VALUES (UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
                ";

现在我需要返回最后插入的 id,它是 MySQL 生成的 UUID。据我所知,UUID 没有 select_last_insert_id() 函数!我为 php 阅读过,您可以先将 UUID() 函数分配给一个变量,然后返回该值。但是如何在 C# 中实现呢?

像这样,但不完全是:

string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint) 
                             VALUES (@UUID = SELECT UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
                ";                  //how to do this here?

这是我的更多代码:

string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint) 
                 VALUES (@UUID = SELECT UUID(), @UId, @LogInTime, @MIp, @MFingerPrint);
                ";

try
{
    if (_conn.State != ConnectionState.Open)
        _conn.Open();
    MySqlCommand cmd = new MySqlCommand(query, _conn);
    cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
    cmd.Parameters.AddWithValue("@LogInTime", DateTime.Now);
    cmd.Parameters.AddWithValue("@MIp", GetMachineIP());
    cmd.Parameters.AddWithValue("@MFingerPrint", GetHardwareFingerPrint());

    var s= Convert.ToString(cmd.ExecuteScalar()); //this returns an empty string :(
    //I need to get it to any .NET data type, string, or Guid or byte[] or anything. 

但是我需要在这样的查询s中的另一个WHERE子句中使用这种数据类型:

string query = @"UPDATE session SET logout_time = @LogOutTime 
                 WHERE user_id = @UId AND PK_Id = @SessionId";

try
{
    if (_conn.State != ConnectionState.Open)
        _conn.Open();
    MySqlCommand cmd = new MySqlCommand(query, _conn);
    cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
    cmd.Parameters.AddWithValue("@SessionId", s);
    cmd.Parameters.AddWithValue("@LogOutTime", DateTime.Now);
    cmd.ExecuteScalar();

@"SessionId"是同一张表中的 UUID 字段。所以基本上,我怎样才能在 C# 中获取 MySQL varbinary 字段,以便我可以通过在另一个查询中指定 WHERE 来使用该类型进行更新?

在 MySQL 表中,UUID 字段是 varbinary (我希望看到一些不是另一个 php 链接或不要求我切换到数据库中的 char 数据类型的解决方案 :))。

编辑:这里的问题是我们已经将 MySQL 生成的大量 UUID 添加到表中,所以我有点担心将 MySQL UUID 更改为 .NET Guid。如果这是唯一的解决方法,我会考虑的。只是这是我们第一次需要返回插入的 UUID 值,以便我可以在另一个查询中更新另一个时间点。

一个子问题:.NET Guid 与 MySQL UUID 完全一样吗?

4

2 回答 2

2

您可以使用GuidUUID 的 MS 实现类型。您应该知道,在将数据插入数据库时​​,如果 MySQL 驱动程序不熟悉处理 Guid,您可能需要将 Guid 转换为 ByteArray。有关此示例,请参阅使用 C# 在 MySQL 中存储 GUID 。

于 2012-04-05T16:31:36.607 回答
1

我认为您可以继续您的早期实施,而不必依赖 MS Guid,但我担心我为时已晚 :)

string query = @"INSERT INTO session (PK_Id, user_id, login_time, machine_ip, machine_fingerprint) 
                             VALUES (UUID(), @UId, @LogInTime, @MIp, @MFingerPrint); 
                 SELECT PK_Id FROM session WHERE login_time=@LogInTime AND machine_fingerprint=@MFingerPrint; //or something similar which gives you the exact same id - UUID
                ";

try
{
    if (_conn.State != ConnectionState.Open)
        _conn.Open();
    MySqlCommand cmd = new MySqlCommand(query, _conn);
    cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
    cmd.Parameters.AddWithValue("@LogInTime", DateTime.Now);
    cmd.Parameters.AddWithValue("@MIp", GetMachineIP());
    cmd.Parameters.AddWithValue("@MFingerPrint", GetHardwareFingerPrint());

    MySqlDataReader r = cmd.ExecuteReader();

    if (r.Read()) //ensure if it is read only once, else modify your `WHERE` clause accordingly
    {
        var s = (Guid)r[0];
    }
    //or even (Guid)cmd.ExecuteScalar() would work

现在您可以像这样在更新中查询:

string query = @"UPDATE session SET logout_time = @LogOutTime 
                        WHERE user_id = @UId AND PK_Id = @SessionId";

try
{
    if (_conn.State != ConnectionState.Open)
        _conn.Open();
    MySqlCommand cmd = new MySqlCommand(query, _conn);
    cmd.Parameters.AddWithValue("@UId", Utility.usr.Id);
    cmd.Parameters.AddWithValue("@SessionId", s.ToByteArray());
    cmd.Parameters.AddWithValue("@LogOutTime", DateTime.Now);
    cmd.ExecuteNonQuery();

注意:这里我s在查询之前将 Guid 变量转换为字节数组。这很重要,在WHERE子句中,无论是它UPDATE还是SELECT查询中的语句。我会要求你从 varbinary 转移到 MySQL 表中的二进制字段。

编辑:如果您的表会变得非常大,那么插入和选择是一个坏主意,因为SELECT查询是正在运行的附加查询。在那种情况下,@PinnyM 的选择会更好。我真的不认为 MySQL 或任何其他数据库会有默认方式来返回“自定义”插入的 id,这些 id 不是数据库生成的。所以简而言之,我建议你不要这样做..

Edit2:请参阅此答案以获取 .NET 数据类型的二进制值。根据 MySQL .NET 连接器版本,有时强制转换不起作用。

于 2012-04-16T12:29:21.727 回答