如何在向SQLite表插入数据后获取最后一行的Id

5
我正在使用SQLite和SQLite-Net Wrapper来开发WinRT应用程序。其他平台也可能有SQLite,但实现方式可能不同,例如使用SQLite-Net api。
我该如何在SQLite中立即插入最后一行Id?谢谢。
以下是示例代码:
``` using (var db = new SQLite.SQLiteConnection(DBPath)) { var newOrder = new SalesOrder() { CustId = g_intCustId, Customer_No = txtBlkCustomer.Text.Trim(), Order_Date = DateTime.Today };
db.Insert(newOrder);
}
--1--- 更新:我使用的是SQLite-Net Wrapper。我没有使用SQLite-WInRT。
我遇到了以下错误:
无法从用法推断出方法'SQLite.SQLiteConnection.ExecuteScalar(string, params object[])'的类型参数。
请尝试明确指定类型参数。
db.Insert(newOrder); var key = db.ExecuteScalar("SELECT last_insert_rowid()");
---2-- 更新
这是类:
我的问题是:如何在使用上述代码插入记录后立即获取SId。
class SalesOrder { [PrimaryKey, AutoIncrement] public int SId { get; set; }
public int CustId { get; set; } public string Customer_No { get; set; } public DateTime Order_Date { get; set; }
} ```

1
@juergend 这不是PHP。 - CL.
1
这是在WinRT中使用SQLite-Net。 - MilkBottle
3
我有点困惑,为什么一个C#的问题被关闭并标记成一个PHP的问题的重复。 - Shafik Yaghmour
@MilkBottle 我有和你一样的问题,但是我不知道如何更改代码?我应该在哪里找到SQLite.cs文件,我正在使用Nuget。 - Zany
2个回答

7
你的连接中是否有ExecuteScalar方法?然后使用它。
var key = db.ExecuteScalar<int>("SELECT last_insert_rowid()");

1
我收到了上述错误。我做错了什么?我正在使用SQLite-Net。 - MilkBottle
你不需要像这样做吗 ...ExecuteScalar("...", new [] object) - LS_ᴅᴇᴠ
我刚刚安装了这个包,它可以正常工作。另外,“var id = db.Insert(newOrder);”中的id是什么意思?它似乎返回插入记录的标识。你的标识列是int类型吗? - FunksMaName

1
SQLite-net中,Insert方法返回插入的行数(SQLite.cs)。所以如果你想要它返回最后一行的ID,你可以更新它来做到这一点。
当前的实现。
public int Insert (object obj, string extra, Type objType)
{
    if (obj == null || objType == null) {
        return 0;
    }


    var map = GetMapping (objType);

    #if NETFX_CORE
    if (map.PK != null && map.PK.IsAutoGuid)
    {
        // no GetProperty so search our way up the inheritance chain till we find it
        PropertyInfo prop;
        while (objType != null)
        {
            var info = objType.GetTypeInfo();
            prop = info.GetDeclaredProperty(map.PK.PropertyName);
            if (prop != null) 
            {
                if (prop.GetValue(obj, null).Equals(Guid.Empty))
                {
                    prop.SetValue(obj, Guid.NewGuid(), null);
                }
                break; 
            }

            objType = info.BaseType;
        }
    }
    #else
    if (map.PK != null && map.PK.IsAutoGuid) {
        var prop = objType.GetProperty(map.PK.PropertyName);
        if (prop != null) {
            if (prop.GetValue(obj, null).Equals(Guid.Empty)) {
                prop.SetValue(obj, Guid.NewGuid(), null);
            }
        }
    }
    #endif


    var replacing = string.Compare (extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0;

    var cols = replacing ? map.InsertOrReplaceColumns : map.InsertColumns;
    var vals = new object[cols.Length];
    for (var i = 0; i < vals.Length; i++) {
        vals [i] = cols [i].GetValue (obj);
    }

    var insertCmd = map.GetInsertCommand (this, extra);
    var count = insertCmd.ExecuteNonQuery (vals);

    if (map.HasAutoIncPK)
    {
        var id = SQLite3.LastInsertRowid (Handle);
        map.SetAutoIncPK (obj, id);
    }

    return count;
}

更新的实现。

public int Insert (object obj, string extra, Type objType)
{
    if (obj == null || objType == null) {
        return 0;
    }


    var map = GetMapping (objType);

    #if NETFX_CORE
    if (map.PK != null && map.PK.IsAutoGuid)
    {
        // no GetProperty so search our way up the inheritance chain till we find it
        PropertyInfo prop;
        while (objType != null)
        {
            var info = objType.GetTypeInfo();
            prop = info.GetDeclaredProperty(map.PK.PropertyName);
            if (prop != null) 
            {
                if (prop.GetValue(obj, null).Equals(Guid.Empty))
                {
                    prop.SetValue(obj, Guid.NewGuid(), null);
                }
                break; 
            }

            objType = info.BaseType;
        }
    }
    #else
    if (map.PK != null && map.PK.IsAutoGuid) {
        var prop = objType.GetProperty(map.PK.PropertyName);
        if (prop != null) {
            if (prop.GetValue(obj, null).Equals(Guid.Empty)) {
                prop.SetValue(obj, Guid.NewGuid(), null);
            }
        }
    }
    #endif


    var replacing = string.Compare (extra, "OR REPLACE", StringComparison.OrdinalIgnoreCase) == 0;

    var cols = replacing ? map.InsertOrReplaceColumns : map.InsertColumns;
    var vals = new object[cols.Length];
    for (var i = 0; i < vals.Length; i++) {
        vals [i] = cols [i].GetValue (obj);
    }

    var insertCmd = map.GetInsertCommand (this, extra);
    var count = insertCmd.ExecuteNonQuery (vals);
    long id = 0;    //New line
    if (map.HasAutoIncPK)
    {
        id = SQLite3.LastInsertRowid (Handle);  //Updated line
        map.SetAutoIncPK (obj, id);
    }

    //Updated lines
    //return count; //count is row affected, id is primary key
    return (int)id;
    //Updated lines
}

我需要做的是:在表中插入一条记录,并立即获取该记录的主键。在上面的代码中,我使用了db.Insert(newOrder),然后通过newOrder.SId获取主键Id,SId是该表中的主键,这种方法正确吗? - MilkBottle
如果您使用我的解决方案和 var ID = db.Insert(newOrder);,那么ID将是 SId,这是您的主键和自动递增列。 - Farhan Ghumra
1
我认为var ID = db.Insert(newOrder)中的ID不是主键,因为它总是返回1。我尝试了Int Id = newOrder.SId,其中每次创建新记录时Id都不同。你能确认一下吗?谢谢 :) - MilkBottle
可以使用这个 Int Id = newOrder.SId,这会和你的解决方案有什么不同吗? - MilkBottle
不,它是相同的,但如果您使用我的解决方案,则无需编写行“Id = newOrder.SId”,因为它会返回ID。 - Farhan Ghumra
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接