NPoco的:为什么我的删除<Model>()调用,抛出一个NullReferenceException?
题
我正在尝试使用NPoco的Delete()方法从数据库中删除一行。但是它只是抛出一个NullReferenceException。
我已经找到了一个解决方法,但我想知道是否有人知道为什么内置的删除功能按ID删除似乎不适合我。这发生在多个表上。我所有的表都有一个名为ID的标准整数主键,它已在模型中使用 [PrimaryKey("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]
解决方案
按照源在 GitHub存储库 看起来NPoco中有一个bug:
你还没有指定什么类型 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);
...
}
我只包括了前2行,因为它是 PocoDataFactory.ForObject
根据堆栈跟踪引发异常的方法。的代码 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);
原因是 Delete<PurchaseItem>("where id = @0", id);
工作,是它遵循不同的代码路径,其中用于解析的类型 PocoData
来自 typeof(T)
哪里 T
是 PurchaseItem
.