I have a model:
public partial class VisitorLog
{
public int Id { get; set; }
public string VisitorName { get; set; }
public DateTime TimeIn { get; set; }
public DateTime TimeOut { get; set; }
public string CompanyName { get; set; }
public string EmployeeID { get; set; }
public string VisitReason { get; set; }
// Navigation properties
[ForeignKey("EmployeeID")]
public virtual Employee Employee { get; set; }
}
a generic repository:
public class GenericRepository<C, T> : IGenericRepository<T> where T : class where C : DbContext, new()
{
private C _entities = new C();
public C Context
{
get { return _entities; }
set { _entities = value; }
}
public virtual IQueryable<T> GetAll()
{
IQueryable<T> query = _entities.Set<T>();
return query;
}
public IQueryable<T> FindBy(System.Linq.Expressions.Expression<Func<T, bool>> predicate)
{
IQueryable<T> query = _entities.Set<T>().Where(predicate);
return query;
}
public virtual void Add(T entity)
{
_entities.Set<T>().Add(entity);
}
public virtual void Delete(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Deleted;
}
public virtual void Edit(T entity)
{
_entities.Entry(entity).State = System.Data.EntityState.Modified;
}
public virtual void Save()
{
_entities.SaveChanges();
}
}
an interface for the generic repository:
public interface IGenericRepository<T> where T : class
{
IQueryable<T> GetAll();
IQueryable<T> FindBy(Expression<Func<T, bool>> predicate);
void Add(T entity);
void Delete(T entity);
void Edit(T entity);
void Save();
}
my model-specific repository (which inherits the generic):
public class VisitorLogRepository : GenericRepository<VisitorLogDBContext, VisitorLog>, IVisitorLogRepository {
public VisitorLog GetSingle(int id)
{
var query = GetAll().FirstOrDefault(x => x.Id == id);
return query;
}
}
public class SearchViewModel
{
public IEnumerable<VisitorLog> VisitorLogs { get; set; }
}
my controller that is loading a viewmodel into the view:
var searchViewModel = new SearchViewModel
{
VisitorLogs = iVisitorlogRepository.FindBy(v => v.VisitorName.Contains(searchText)
|| v.CompanyName.Contains(searchText)
|| v.EmployeeID.Contains(searchText)),
};
and finally my view:
@model VisitorLogApp.ViewModels.SearchViewModel
@foreach (var item in ViewData.Model.VisitorLogs) {
<tr>
<td>
@Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
@Html.ActionLink("Details", "Details", new { id=item.Id }) |
@Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
<td>
@item.VisitorName
</td>
<td>
@item.CompanyName
</td>
<td>
@item.Employees.EmployeeName
</td>
<td>
@String.Format("{0:g}", item.TimeIn)
</td>
<td>
@String.Format("{0:g}", item.TimeOut)
</td>
<td>
@item.VisitReason
</td>
</tr>
Everything is working great with one exception. The view shows a list of Visitors (VisitorLog). Using navigation properties I was able to get the EmployeeName value to show instead of the employee ID from the VisitorLog class by simply using @item.Employees.EmployeeName. However, I also want to be able to search by employee name in my repository call in the controller:
VisitorLogs = iVisitorlogRepository.FindBy(v => v.VisitorName.Contains(searchText)
|| v.CompanyName.Contains(searchText)
|| v.Employees.EmployeeName.Contains(searchText)),
but Employees.EmployeeName in the example above is not showing as an option in the list members for "v".
Any help is appreciated.
Looks like this might just be a typo - the navigation property in your class is called Employee
, not Employees
. Does the following work?
VisitorLogs = iVisitorlogRepository.FindBy(
v => v.VisitorName.Contains(searchText)
|| v.CompanyName.Contains(searchText)
|| v.Employee.EmployeeName.Contains(searchText)),
If this was the reason, you've done the same thing in the View.