2016-02-18 3 views
1

J'ai une couche logique métier et une couche DB (Entity Framework). Par exemple, je reçois des données de DB.Aucun enregistrement - lieu d'exception

couche DB:

public SmartphonePhotographerResponseManage ResponseManage(int RequestID) 
{ 
    SmartphonePhotographerResponseManage response = (from i in db.SmartphonePhotographerResponses 
                where i.RequestID == RequestID 
                select new SmartphonePhotographerResponseManage() 
                { 
                 ResponseID = i.ID, 
                 FormattedAddress = i.EditorialPixlocateRequest.FormattedAddress 
                }).FirstOrDefault(); 
    return response; 
} 

couche BL (il est l'exemple le plus simple, le sens de la couche BL - juste "jeter" résultat de la DB au client (ASP.NET MVC dans mon cas, mais peu importe). Bien sûr, la méthode BL peut avoir n'importe quelle logique supplémentaire):

public SmartphonePhotographerResponseManage ResponseManage(int RequestID) 
    { 
     return _repository.ResponseManage(RequestID); 
    } 

Cela fonctionne et fonctionne bien. Mais je veux lancer ma propre exception si l'enregistrement n'existe pas (c.-à-enregistrement a été supprimé, mais l'utilisateur a lien vers ses signets):

public class RecordNotFoundException<T> : Exception 
{ 
    public RecordNotFoundException(T ID) : base(String.Format("No Records for passed ID={0}", ID.ToString())) 
    { 
    } 
} 

J'ai 2 façon de le jeter: 1. Dans la couche DB:

public SmartphonePhotographerResponseManage ResponseManage(int RequestID) 
{ 
    SmartphonePhotographerResponseManage response = (from i in db.SmartphonePhotographerResponses 
                where i.RequestID == RequestID 
                select new SmartphonePhotographerResponseManage() 
                { 
                 ResponseID = i.ID, 
                 FormattedAddress = i.EditorialPixlocateRequest.FormattedAddress 
                }).FirstOrDefault(); 
    if (response == null) 
     throw new RecordNotFoundException<int>(RequestID); 
    return response; 
} 

ou dans la couche BL:

public SmartphonePhotographerResponseManage ResponseManage(int RequestID) 
{ 
    var response = _repository.ResponseManage(RequestID); 
    if (response == null) 
     throw new RecordNotFoundException<int>(RequestID); 
    return response; 
} 

et ensuite de prendre cette exception côté client (contrôleur de ASP.NET MVC par exemple) et la poignée par voie appropriée. Les deux approches vont fonctionner, mais où est l'endroit le plus logique pour lancer une telle exception?

EDIT: Il est également difficile de lancer cette exception dans BL lorsque je souhaite modifier/supprimer un enregistrement. C'est à dire. J'ai le code:

public async Task AcceptOrDeclineFileAsync(int ElementID, bool accept, string smsSid) 
{ 
    var element = (from i in db.SmartphonePhotographerResponseElements where i.ID == ElementID select i).FirstOrDefault(); 
    if (element == null) 
     throw new CommonLibrary.RecordNotFoundException<int>(ElementID); 

    element.ApprovedByEditorial = accept; 
    element.SmsSID = smsSid; 
    await db.SaveChangesAsync(); 
} 

Si je ne jette exception dans la couche DB je reçois type d'exception commune (je suppose, NullReferenceException) dans BL. Peut-être, c'est assez? Toutes les autres situations, quand je peux obtenir NullReferenceException?

Répondre

3

Je mettrais l'exception dans votre erreur Business Logic. Le calque de base de données devrait simplement rapporter ce qu'il retourne; rien dans ce cas. C'est seulement un problème parce que votre logique métier l'exige. Donc, jetez l'erreur ici plutôt qu'à un niveau inférieur.

+0

mais il vous interdit de faire 2 demandes ou plus dans une méthode de couche DB (car le résultat de la première requête peut être nul) –

+1

J'essaie de rendre ma couche DB aussi mince que possible. Si votre interface utilisateur ou votre flux de travail doit effectuer 2 appels de base de données, il doit être clair du côté de la base de données qu'il effectue plusieurs déplacements dans la base de données. L'abstraction de la couche de base de données masque les problèmes de performances potentiels. Votre couche BL peut faire plusieurs appels DB distincts en tant qu'appel logique unique, mais comme il s'agit d'un appel logique, elle doit figurer dans la couche BL. – Necoras

+0

mais si je veux utiliser la transaction? C'est à dire. supprimer l'enregistrement d'une table et ajouter à la seconde ... –