如何将MySQL生成的UUID转换为C#变量

时间:2012-04-05 16:07:41

标签: c# mysql .net-2.0 uuid varbinary

以下是查询:

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数据类型)。)。< / p>

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

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分: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();

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

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

Edit2 :有关将二进制值转换为.NET数据类型的信息,请参阅此answer。有时,根据MySQL .NET连接器版本,转换不起作用..

答案 2 :(得分:-1)

您也可以使用sproc中的out参数完成此操作。见NerfAnvil的回复:

How to get OUT parameter from MySQL stored procedure是一个几乎确切的例子。

  

cmd.Parameters [“outnextnoteid”]。Direction = ParameterDirection.Output;

     

...

     

nextNoteId =(int)cmd.Parameters [“outnextnoteid”]。值;