问题
This question is related to this
I have decided to change the Generic Repository pattern and used a specific repository for each entity. However I just cant find how to make it work because in my html I need to show some fields from related entities.
Is it better to replace Ienumerable with Iqueryable?
Repository Interface
public interface IApplicantPositionRepository : IDisposable
{
IEnumerable<ApplicationPositionHistory> GetApplicationPositionHistories(int applicantId, int positionId);
void Save();
}
Repository Interface Implementation.
public IEnumerable<ApplicationPositionHistory> GetApplicationPositionHistories(int applicantId, int positionId)
{
return context.ApplicationsPositionHistory.Where(d => d.applicantPosition.ApplicantID == applicantId && d.applicantPosition.PositionID == positionId);
}
Controller Method
public ViewResult History(int applicantId, int positionId)
{
var history=applicantPositionRepository.GetApplicationPositionHistories(applicantId, positionId);
return View(history);
}
Html.
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.applicantPosition.Applicant.name)
</td>
<td>
@Html.DisplayFor(modelItem => item.applicantPosition.Position.name)
</td>
回答1:
Personally I like IList<T> but thats a personal choice of course
To include a related table simply do (this syntax of not using a string for RelatedEntityName like .Include("RelatedEntityName") I think was added in 4.1 if I recall correctly:
return context.ApplicationsPositionHistory.Where(d => d.applicantPosition.ApplicantID == applicantId && d.applicantPosition.PositionID == positionId).Include(o=>o.RelatedEntityName);
Never return IQueryable from a repository. It's not easily testable since this is very provider specific.
I would also create separate methods if the caller does not require additional details either.
回答2:
To answer your second question:
It is definitely preferable to use IQueryable instead of IEnumerable. Doing that you can do things like this:
Controller:
public ActionResult Index(int page = 1, int pageSize = 10)
{
IQueryable<Entity> items = repository.GetEntities();
items = items.ApplyPaging(page, pageSize);
return View(items);
}
You could create an extension method off of IQueryable called ApplyPaging that looks like:
public static class QueryableExtensions
{
public static IQueryable<T> ApplyPaging<T>(this IQueryable<T> source, int page = 1, int pageSize = 10)
{
return source.Skip((page - 1) * pageSize).Take(pageSize);
}
}
If it was IEnumerable then the paging could be done by the client instead of the database building the query correctly.
来源:https://stackoverflow.com/questions/7917261/how-to-load-the-related-entities-using-entity-framework-and-the-repository-patte