3

NPoco の Delete() メソッドを使用して、データベースから行を削除しようとしています。ただし、NullReferenceException をスローするだけです。

回避策を見つけましたが、ID で削除する組み込みの削除機能が機能しないように見える理由を誰かが知っているかどうか疑問に思っています。これは複数のテーブルで発生します。[PrimaryKey("ID")]私のすべてのテーブルには、デコレータを使用してモデルでフラグが付けられた、ID と呼ばれる標準の整数主キーがあります。

オブジェクト参照がオブジェクト インスタンスに設定されていません。

Delete<PurchaseItem>(id); // throws null reference exception.
Delete<PurchaseItem>("where id = @0", id);  // works.

渡される ID は有効で、アイテムはデータベースにあります。このコードは、SQL を実行するまでには至りません。

スタックトレース:

[NullReferenceException: Object reference not set to an instance of an object.]
   NPoco.PocoDataFactory.ForObject(Object o, String primaryKeyName) in d:\Adam\projects\NPoco\src\NPoco\PocoDataFactory.cs:41
   NPoco.Database.Delete(String tableName, String primaryKeyName, Object poco, Object primaryKeyValue) in d:\Adam\projects\NPoco\src\NPoco\Database.cs:1587
   NPoco.Database.Delete(Object pocoOrPrimaryKey) in d:\Adam\projects\NPoco\src\NPoco\Database.cs:1598
   Harmsworth.DAL.HarmsworthDB.DeletePurchaseItemFromBasketByID(Int32 id) in c:\inetpub\wwwroot\harmsworth\Website\classes\HarmsworthDAL.cs:224
   Harmsworth.ViewBasketPage.RemoveItem(Int32 id) in c:\inetpub\wwwroot\harmsworth\Website\view-basket.aspx.cs:187
   Harmsworth.ViewBasketPage.PurchaseItemsRepeater_ItemCommand(Object sender, RepeaterCommandEventArgs e) in c:\inetpub\wwwroot\harmsworth\Website\view-basket.aspx.cs:75
   System.Web.UI.WebControls.Repeater.OnItemCommand(RepeaterCommandEventArgs e) +111
   [more redundant trace info]
4

1 に答える 1

3

GitHub リポジトリのソースをたどると、NPoco にバグがあるようです。

タイプが何であるかを指定していませんidが、それが int であり、次のコードがあると仮定します。

var id = 12345;
Delete<PurchaseItem>(id);

NPoco を呼び出すDelete<T>(object pocoOrPrimaryKey)コードは次のとおりです。

public int Delete<T>(object pocoOrPrimaryKey)
{
    if (pocoOrPrimaryKey.GetType() == typeof(T))
        return Delete(pocoOrPrimaryKey);
    var pd = PocoDataFactory.ForType(typeof(T));
    return Delete(pd.TableInfo.TableName, pd.TableInfo.PrimaryKey, null, pocoOrPrimaryKey); // This is the method your code calls
}

次に NPoco を呼び出しますDelete(string tableName, string primaryKeyName, object poco, object primaryKeyValue)。コードは次のとおりです。

public virtual int Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue)
{
    if (!OnDeleting(new DeleteContext(poco, tableName, primaryKeyName, primaryKeyValue))) return 0;
    var pd = PocoDataFactory.ForObject(poco, primaryKeyName);
    ...
}

PocoDataFactory.ForObjectスタック トレースに従って例外をスローするメソッドであるため、最初の 2 行のみを含めました。コードForObject(object o, string primaryKeyName)は次のとおりです。

public PocoData ForObject(object o, string primaryKeyName)
{
    var t = o.GetType(); // This is where the exception comes from
    ...
}

何が起こっているかを次に示します (ID が 12345 であると仮定すると、テーブルは PurchaseItem としてマップされ、主キーは Id としてマップされます)。

Delete<PurchaseItem>(pocoOrPrimaryKey : 12345);
Delete(tableName: "PurchaseItem", primaryKeyName: "Id", poco: null, primaryKeyValue: 12345);
PocoDataFactory.ForObject(o: null, primaryKeyName: Id);

機能する理由は、 を解決するために使用される型が where isから来るDelete<PurchaseItem>("where id = @0", id);別のコード パスに従うためです。PocoDatatypeof(T)TPurchaseItem

于 2014-08-01T15:11:11.487 に答える