NPoco:Porque é que a minha Excluir<Model>() chamada, jogando uma NullReferenceException?

StackOverflow https://stackoverflow.com//questions/25082377

  •  02-01-2020
  •  | 
  •  

Pergunta

Eu estou tentando usar o NPoco do método Delete() para excluir uma linha do banco de dados.No entanto, ele apenas lança uma exceção NullReferenceException.

Eu encontrei uma solução, mas eu estou querendo saber se alguém sabe por que o construído em função delete para excluir o ID não parecem funcionar para mim.Isso acontece em várias tabelas.Todas as minhas tabelas têm um padrão integer chave primária ID de chamada, que tem sido sinalizado no modelo usando o [PrimaryKey("ID")] decorador.

Referência de objeto não definida para uma instância de um objeto.

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

A identificação do que está sendo passada é válido um item no banco de dados.O código NÃO chegar tão longe como a execução de qualquer SQL.

Rastreamento De Pilha:

[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]
Foi útil?

Solução

A seguir a origem no Repositório no GitHub parece que há um bug no NPoco:

Você não especificou o tipo id é, mas eu vou assumir que é um int e você terá o seguinte código:

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

O que chama NPoco Delete<T>(object pocoOrPrimaryKey), o código é:

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
}

Que por sua vez chama NPoco Delete(string tableName, string primaryKeyName, object poco, object primaryKeyValue), o código é:

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);
    ...
}

Incluí somente as 2 primeiras linhas, como é o PocoDataFactory.ForObject método que lança a exceção, de acordo com o rastreamento de pilha.O código para ForObject(object o, string primaryKeyName) é:

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

Aqui está o que está acontecendo (supondo que o id é 12345, a tabela é mapeado como PurchaseItem e a chave primária é mapeado como documento de Identificação):

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

A razão que Delete<PurchaseItem>("where id = @0", id); funciona, é que ele segue um caminho de código diferente, onde o tipo usado para resolver o PocoData vem de typeof(T) onde T é PurchaseItem.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top