L'exemple donné par Codeka est correct, et je Je conseillerais d'écrire votre code avec ceci quand la méthode est appelée par la couche de présentation. Cependant, disposer de classes DataContext
est un peu difficile, donc j'aime ajouter quelque chose à ce sujet. Les objets de domaine générés par LINQ to SQL (dans votre cas, la classe TB_Countries
) contiennent souvent une référence à la classe DataContext
.Cette référence interne est nécessaire pour le chargement paresseux. Lorsque vous accédez par exemple à la liste des objets référencés (disons par exemple: TB_Country.States
) LINQ to SQL interrogera la base de données pour vous. Cela se produira également avec des colonnes chargées paresseuses. Lorsque vous disposez du DataContext
, vous évitez qu'il soit à nouveau utilisé. Par conséquent, lorsque vous renvoyez un ensemble d'objets comme vous l'avez fait dans votre exemple, il est impossible d'appeler la propriété States
sur une instance TB_Country
, car elle va lancer un ObjectDisposedException
. Cela ne veut pas dire que vous ne devez pas jeter le DataContext
, parce que je crois que vous devriez le faire. Comment résoudre ce problème dépend un peu de l'architecture que vous choisissez, mais vous avez essentiellement deux options:
Option 1. Fournissez un DataContext
à la méthode GetCountriesQ
. Normalement, vous voulez le faire lorsque votre méthode est une méthode interne de votre couche de gestion et qu'elle fait partie d'une transaction plus importante (entreprise). Lorsque vous fournissez un DataContext
de l'extérieur, il est créé en dehors de la portée de la méthode et il ne doit pas le jeter. Vous pouvez le disposer à un niveau supérieur. Dans cette situation, votre méthode ressemble fondamentalement ceci:
public static IQueryable<TB_Country> GetCountriesQ(
Bn_Master_DataDataContext db)
{
return db.TB_Countries.OrderBy(o => o.CountryName);
}
Option 2. Ne pas renvoyer aucun objet de domaine de la méthode GetCountriesQ
. Cette solution est utile lorsque la méthode est publique dans votre couche de gestion et sera appelée par la couche de présentation. Vous pouvez envelopper les données dans un objet spécialement conçu (un DTO) qui contient uniquement des données et aucune référence cachée au DataContext
. De cette façon, vous avez un contrôle total sur la communication avec la base de données et vous pouvez disposer du DataContext
comme vous le devriez. J'ai écrit plus à propos de son sur SO here. Dans cette situation, votre méthode ressemble fondamentalement ceci:
public static CountryDTO[] GetCountriesQ()
{
using (var db = new Bn_Master_DataDataContext())
{
var countries;
from country in db.TB_Countries
orderby country.CountryName
select new CountryDTO()
{
Name = country.CountryName,
States = (
from state in country.States
order by state.Name
select state.Name).ToList();
};
return countries.ToArray();
}
}
public class CountryDTO
{
public string Name { get; set; }
public List<StateDTO> States { get; set; }
}
Comme vous le lirez here il y a des choses intelligentes que vous pouvez faire qui rendent l'utilisation DTO moins douloureux.
J'espère que cela aide.
N'oubliez pas d'indiquer votre réponse favorite. – Steven