The problem I'm having goes like this:
I have a textbox in my view that allows search/filter functionality of the Orders table. However, I would like it to be able to also search by the child table OrderDetails and filter appropriately.
The search textbox works for the order table but not the order details.
I realize this code can be shrunk down a lot but I'm new coding.
Something that may help - I'm doing Database first
Here is my code so far.
Controller:
EntitiesDB db = new EntitiesDB();
#region INDEX MAIN PAGE
[HttpGet]
public ActionResult Index(string sortOrder, string currentFilter, int? page, string jobNumberDropDown, string requesitionerDropDown, string supplierDropDown, string dateRequestedDropDown, string dateRequiredDropDown, string searchString)
{
var getSupplierList = db.Suppliers.OrderBy(SL => SL.SupplierName).ToList();
var getEmployeeList = db.Employees.OrderBy(EL => EL.FullName).ToList();
SelectList listOfSuppliers = new SelectList(getSupplierList, "SupplierName", "SupplierName");
SelectList listOfEmployees = new SelectList(getEmployeeList, "FullName", "FullName");
ViewBag.supplierNames = listOfSuppliers;
ViewBag.employeeNames = listOfEmployees;
#region PAGINATION FUNCTION
//Code for Paging
ViewBag.CurrentSort = sortOrder;
if (searchString != null)
{
page = 1;
}
else
{
searchString = currentFilter;
}
ViewBag.CurrentFilter = currentFilter;
int pageSize = 10;
int pageNumber = (page ?? 1);
#endregion
#region SEARCH FUNCTION
//Creates the LINQ Query to select the Orders from the ORDERS table
//var orders = from o in db.Orders join c in db.OrderDetails on o.OrderID equals c.OrderID select new { orders = o.JobNumber, o.PurchaseOrder, c.Description, c.PartNumber, c.AngstromPartNumber };
var orders = from o in db.Orders.Where(x => x.IsDeleted != true) select o; /*-****WORKING FOR ORDER TABLE*****/
var orderDetails = from od in db.OrderDetails.Where(x => x.IsDeleted != true) select od;
//List of Employees
var requesitionerList = new List<string>();
//List of Suppliers
var supplierList = new List<string>();
//List of Job Numbers
var jobNumberList = new List<string>();
//List of Dates Requested
var dateRequestedList = new List<DateTime>();
//List of Dates Required
var dateRequiredList = new List<DateTime>();
//Query the ORDERS table columns
var requesitionerQry = from r in db.Orders.Where(x => x.IsDeleted != true) orderby r.Requesitioner select r.Requesitioner;
var supplierQry = from s in db.Orders.Where(x => x.IsDeleted != true) orderby s.Supplier select s.Supplier;
var jobNumberQry = from j in db.Orders.Where(x => x.IsDeleted != true) orderby j.JobNumber select j.JobNumber;
var dateRequestedQry = from DRqst in db.Orders.Where(x => x.IsDeleted != true) orderby DRqst.DateRequested select DRqst.DateRequested;
var dateRequiredQry = from DRqrd in db.Orders.Where(x => x.IsDeleted != true) orderby DRqrd.DateRequired select DRqrd.DateRequired;
//Searches through the columns filters out NULLS
var t = requesitionerQry.Distinct().ToList().Where(x => String.IsNullOrWhiteSpace(x) == false);
var u = supplierQry.Distinct().ToList().Where(y => String.IsNullOrWhiteSpace(y) == false);
var v = jobNumberQry.Distinct().ToList().Where(z => String.IsNullOrWhiteSpace(z) == false);
var dRT = dateRequestedQry.Distinct().ToList().Where(z1 => String.IsNullOrWhiteSpace(z1.ToString()) == false);
var dRD = dateRequiredQry.Distinct().ToList().Where(z2 => String.IsNullOrWhiteSpace(z2.ToString()) == false);
//Searches through the columns and only pulls out one of each unique string
requesitionerList.AddRange(t);
supplierList.AddRange(u);
jobNumberList.AddRange(v);
dateRequestedList.AddRange(dRT);
dateRequiredList.AddRange(dRD);
//I believe this Grabs the list items and arranges them into a viewable anonamous object
ViewBag.requesitionerDropDown = new SelectList(requesitionerList);
ViewBag.supplierDropDown = new SelectList(supplierList);
ViewBag.jobNumberDropDown = new SelectList(jobNumberList);
ViewBag.dateRequestedDropDown = new SelectList(dateRequestedList);
ViewBag.dateRequiredDropDown = new SelectList(dateRequiredList);
//This defines which columns the text in the search textbox should locate
if (!String.IsNullOrEmpty(searchString))
{
orders = orders.Where(a => a.JobNumber.Contains(searchString)||
//a.Description.Contains(searchString) || a.PartNumber.Contains(searchString) || a.AngstromPartNumber.Contains(searchString) ||
a.Supplier.Contains(searchString) || a.Reason.Contains(searchString) || a.Requesitioner.Contains(searchString) ||
a.DateRequested.ToString().Contains(searchString) || a.DateRequired.ToString().Contains(searchString) ||
a.ExpectedDate.ToString().Contains(searchString) || a.DateOrderPlaced.ToString().Contains(searchString) ||
a.PurchaseOrder.ToString().Contains(searchString));
}
if (!String.IsNullOrEmpty(searchString))
{
orders = orders.Where(x => x.OrderDetails.Any(i => i.Description.Contains(searchString)));
}
//Search the REQUESITIONER column
if (!String.IsNullOrEmpty(requesitionerDropDown))
{
orders = orders.Where(b => b.Requesitioner == requesitionerDropDown);
}
//Search the SUPPLIER column
if (!String.IsNullOrEmpty(supplierDropDown))
{
orders = orders.Where(c => c.Supplier == supplierDropDown);
}
//Search the JOBNUMBER column
if (!String.IsNullOrEmpty(jobNumberDropDown))
{
orders = orders.Where(d => d.JobNumber == jobNumberDropDown);
}
if (!String.IsNullOrEmpty(dateRequestedDropDown))
{
orders = orders.Where(d => d.DateRequested.ToShortDateString() == dateRequestedDropDown);
}
if (!String.IsNullOrEmpty(dateRequiredDropDown))
{
orders = orders.Where(d => d.DateRequired.ToShortDateString() == dateRequiredDropDown);
}
#endregion
//List<Order> OrderList = db.Orders.ToList();
var sortedOrders = orders.OrderBy(x => x.JobNumber);
return View(sortedOrders.ToPagedList(pageNumber, pageSize));
}
#endregion
Here are my Models:
public partial class Order
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Order()
{
this.OrderDetails = new HashSet<OrderDetail>();
}
public System.Guid OrderID { get; set; }
public Nullable<bool> IsDeleted { get; set; }
public string JobNumber { get; set; }
public string Supplier { get; set; }
public string Reason { get; set; }
public string Requesitioner { get; set; }
public System.DateTime DateRequested { get; set; }
public System.DateTime DateRequired { get; set; }
public Nullable<bool> Urgent { get; set; }
public System.DateTime ExpectedDate { get; set; }
public System.DateTime DateOrderPlaced { get; set; }
public string PurchaseOrder { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<OrderDetail> OrderDetails { get; set; }
}
public partial class OrderDetail
{
public System.Guid OrderDetailID { get; set; }
public Nullable<bool> IsDeleted { get; set; }
public int Quantity { get; set; }
public string Description { get; set; }
public string PartNumber { get; set; }
public string Notes { get; set; }
public string Comments { get; set; }
public Nullable<decimal> UnitPrice { get; set; }
public string AngstromPartNumber { get; set; }
public string Manufacturer { get; set; }
public Nullable<int> BoneYard { get; set; }
public System.Guid OrderID { get; set; }
public Nullable<System.Guid> EmployeeID { get; set; }
public Nullable<System.Guid> SupplierID { get; set; }
public virtual Employee Employee { get; set; }
public virtual Order Order { get; set; }
public virtual Supplier Supplier { get; set; }
}
Related
I am trying to Edit existing instance of class project using a viewmodel. I think I have no issues in the GET method of the Edit (everything renders fine on the View) but I am struggling with the POST method. The problem is the POST method creates new instance of the project instead updating the current one.
This is my model:
public class Project
{
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
public Project()
{
}
}
}
This is my CreateProjectViewModel (some of the attributes are not used in the controller code below):
public class CreateProjectViewModel
{
//project
public int ProjectId { get; set; }
public string Name { get; set; }
public string Budget { get; set; }
public string BusinessCase { get; set; }
public string StartDate { get; set; }
public string FinishDate { get; set; }
//clients
public int ClientId { get; set; }
public Client Client { get; set; }
public ICollection<ProjectMember> ProjectMembers { get; set; }
//Members
public int MemberId { get; set; }
public Member Member { get; set; }
public Project Project { get; set; }
public List<SelectListItem> Members { get; set; }
public IEnumerable<SelectListItem> Clients { get; set; }
public IEnumerable<int> SelectedMembers { get; set; }
public CreateProjectViewModel() { }
}
}
This is My Edit GET method in ProjectController:
public async Task<IActionResult> Edit(int? id)
{
Project project = await _context.Project
.FirstOrDefaultAsync(m => m.ProjectId == id);
var members = _context.Member
.Select(m => new SelectListItem { Value = m.MemberId.ToString(), Text = m.MemberName }).ToList();
var clients = _context.Client
.Select(r => new SelectListItem { Value = r.ClientId.ToString(), Text = r.Name }).ToList();
CreateProjectViewModel viewmodel = new CreateProjectViewModel
{
Name = project.Name,
Budget = project.Budget,
BusinessCase = project.BusinessCase,
StartDate = project.StartDate,
FinishDate = project.FinishDate,
Project = project,
Clients = clients,
Members = members
};
return View(viewmodel);
This is my Edit POST method in ProjectController which is wrongly creating a new project instead of updating the current project:
(The controller is trying to save values to Project Model and at the same time in Join table containing MemberId and ProjectID - this works fine when creating a project, not sure if correct for updating)
public IActionResult Edit(int? id, CreateProjectViewModel model)
{
Project project = _context.Project
.Single(m => m.ProjectId == id);
//this is to post in many-to-many join table between Member and Project
var projectID = project.ProjectId;
var memberID = model.MemberId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
foreach (var selectedId in model.SelectedMembers)
{
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
//this is to update the values in the project which refers to ProjectID
project.ProjectId = model.ProjectId;
project.Name = model.Name;
project.Budget = model.Budget;
project.BusinessCase = model.BusinessCase;
project.StartDate = model.StartDate;
project.FinishDate = model.FinishDate;
project.ClientId = model.ClientId;
_context.Entry(project).State = EntityState.Modified;
_context.SaveChanges();
return RedirectToAction("Index");
}
Can you guys advise me what should be changed in either method to get the expected result?
Thanks a lot.
After some digging done this is the working code.
Edit POST Method:
public IActionResult Edit(int? id, CreateProjectViewModel viewmodel)
{
if (ModelState.IsValid)
{
var project = _context.Project
.SingleOrDefault(m => m.ProjectId == id);
//this is to update the Project from the viewmodel
project.Name = viewmodel.Name;
project.Budget = viewmodel.Budget;
project.BusinessCase = viewmodel.BusinessCase;
project.StartDate = viewmodel.StartDate;
project.FinishDate = viewmodel.FinishDate;
project.ClientId = viewmodel.ClientId;
//code below is to validate if the matched primary keys of Project and Member are not already in ProjectMembers table
foreach (var selectedId in viewmodel.SelectedMembers)
{
var projectID = project.ProjectId;
var memberID = selectedId;
IList<ProjectMember> existingItems = _context.ProjectMembers
.Where(cm => cm.MemberId == memberID)
.Where(cm => cm.ProjectId == projectID).ToList();
if (existingItems.Count == 0)
{
//this is to add new entry into ProjectMembers table
_context.ProjectMembers.Add(new ProjectMember
{
ProjectId = project.ProjectId,
MemberId = selectedId,
});
}
}
_context.SaveChanges();
}
return RedirectToAction("Index");
I have got problem with return data from my database. In my database are three tables: Customer, Activity and CustomerActivity. I want to return activities data for specific customer and with specific type activity. I wrote query but it doesn't work exactly as I wish. Here is my code and tables. Thank you for advices.
var activities = db.Join(db.CustomerActivities, a => a.ActivityID, ca =>ca.CustomerActivityID, (a, ca) => new { Activity = a, CustomerActivity = ca })
.Where(a => a.CustomerActivity.customer.CustomerID == id && a.Activity.TypeActivityID == typeActivity)
.Select(m => new ActivityMV()
{
ActivityID = m.Activity.ActivityID,
Name = m.Activity.Name,
DateOfActivity = m.Activity.DateOfActivity,
Desc = m.Activity.Desc
})
.ToList();
public class CustomerActivity
{
public int CustomerActivityID { get; set; }
public int CustomerID { get; set; }
public int ActivityID { get; set; }
public virtual Customer customer { get; set; }
public virtual Activity activity { get; set; }
}
public class Activity
{
public int ActivityID { get; set; }
public string Name { get; set; }
public string Desc { get; set; }
public string DateOfActivity { get; set; }
public string TypeActivityID { get; set; }
public virtual ICollection <CustomerActivity> customerActivities { get; set; }
}
Try
var activities = db.CustomerActivities
.Where(ca => ca.CustomerID == id && ca.Activity.TypeActivityID == typeActivity)
.Select(ca => new ActivityMV()
{
ActivityID = ca.ActivityID,
Name = ca.Activity.Name,
DateOfActivity = ca.Activity.DateOfActivity,
Desc = ca.Activity.Desc
})
.ToList();
I'm using jquery datatable for showing my data.I want to use server side proccesing in jquery datatable using asp.net mvc but I've a problem with it.I have a class that it hasn't GoodName property but I want to sort my table based on GoodName property.but i've got error 'No property or field 'GoodName' exists in type 'GoodDomain' I know that GoodName doesn't exist in GoodDomian but i can access GoodName property by navigation property Good.GooName but I can't use it in this statement.because I've used Linq.Dynamic
query = query.OrderBy(orderByString == string.Empty ? "GoodName asc + " : orderByString);
public ActionResult LoadData([ModelBinder(typeof(DataTablesBinder))] IDataTablesRequest requestModel)
{
IQueryable<GoodDomain> query = db.GoodDomains;
var totalCount = query.Count();
#region Filtering
// Apply filters for searching
if (requestModel.Search.Value != string.Empty)
{
var value = requestModel.Search.Value.Trim();
query = query.Where(p =>
p.Good.GoodName.Contains(value)
);
}
var filteredCount = query.Count();
#endregion Filtering
#region Sorting
// Sorting
var sortedColumns = requestModel.Columns.GetSortedColumns();
var orderByString = String.Empty;
foreach (var column in sortedColumns)
{
orderByString += orderByString != String.Empty ? "," : "";
orderByString += (column.Data) + (column.SortDirection == Column.OrderDirection.Ascendant ? " asc" : " desc");
}
query = query.OrderBy(orderByString == string.Empty ? "MinRage asc + " : orderByString); // I've a problem
//query =db.GoodDomains.OrderBy( g => g.Good.GoodName)
#endregion Sorting
// Paging
query = query.Skip(requestModel.Start).Take(requestModel.Length);
var data = query.Select(g => new
{
GoodDomainID = g.GoodDomainID,
GoodName = g.Good.GoodName,
GoodHeadName = g.GoodHead.GoodHeadName,
GoodFootName = g.GoodFoot.GoodFootName,
WorkhouseName = g.Workhouse.WorkhouseName,
MinRange = g.MinRange,
MaxRange = g.MaxRange,
}).ToList();
return Json(new DataTablesResponse(requestModel.Draw, data, filteredCount, totalCount), JsonRequestBehavior.AllowGet);
}
public class GoodDomain
{
[Key]
public int GoodDomainID { get; set; }
public Nullable<int> GoodHeadeId { get; set; }
public virtual GoodHead GoodHead { get; set; }
public Nullable<int> GoodFootId { get; set; }
public virtual GoodFoot GoodFoot { get; set; }
public Nullable<int> GoodId { get; set; }
public virtual Good Good { get; set; }
[Display(Name = "نام کارگاه")]
public Nullable<int> WorkhouseId { get; set; }
public virtual Workhouse Workhouse { get; set; }
public Nullable<int> MaxRange { get; set; }
public Nullable<int> MinRange { get; set; }
}
I would like to get a result set from both PriceAssocationLookup and PriceAssociation tables. How do I do this and not get an error due to Anonymous Type?
Here is my code:
IEnumerable<IPriceAssociationLookupRepository> IPriceAssociationLookupRepository.GetPacs(string upc)
{
using (PortalDataEntities entities = new PortalDataEntities())
{
var priceAssociationLookups = (from priceassociationlookup in entities.PriceAssociationLookups
join priceassociation in entities.PriceAssociations on priceassociationlookup.PriceAssociationCode equals priceassociation.PriceAssociationCode
where priceassociationlookup.Upc == upc
select priceassociationlookup ).ToList();
return priceAssociationLookups;
}
}
Create a ViewModel and add properties for the columns you want to return and return List of the view model type, here is my code, the way i used to do :
List<PreviousTest> Result = (from d in db.dc_tpatient_bookingd
join og in db.dc_tp_organization
on d.clientid equals og.OrgId into a
from og in a.DefaultIfEmpty()
from t in db.dc_tp_test
from p in db.dc_tp_tprocess
where d.bookingid == BookingID
&& t.TestId == d.testid
&& d.ProcessID == p.processid
&& d.bookingdid != BookingDID
select new PreviousTest
{
BookingID = d.bookingid,
BookingDId = d.bookingdid,
TestID = t.TestId,
TestName = t.Test_Name,
ProcessName = p.name,
ProcessID = p.processid,
ClientID = d.clientid
}).ToList();
Here is my viewmodel :
public class PreviousTest
{
public long BookingID { get; set; }
public long BookingDId { get; set; }
public long TestID { get; set; }
public string TestName { get; set; }
public long ProcessID { get; set; }
public string ProcessName { get; set; }
public string ClientID { get; set; }
}
There are Supplier model and User model in my project, every Supplier has a few Users
Supplier model
public class SupplierRow
{
public Guid Id { get; set; }
public string FullName { get; set; }
public bool Subscribed { get; set; }
public bool Active { get; set; }
public int Visits { get; set; }
public List<UserRow> Users { get; set; }
public bool AllInactive
{
get
{
foreach (UserRow ur in Users)
{
if (ur.Status == 1) return false;
}
return true;
}
}
}
and User model
public class UserRow
{
public Guid Id { get; set; }
public string FullName { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public int Status { get; set; }
public int Role { get; set; }
public Guid SupplierId { get; set; }
}
then I use my models in controller
public ActionResult Grid(bool? active)
{
var suppliers = Context.Suppliers.AsNoTracking()
.WhereIf(active != null, e => e.Active == active)
.Select(e => new SupplierRow
{
Id = e.Id,
FullName = e.FullName,
Active = e.Active,
Visits = e.Visits,
})
.ToList();
List<Guid> supplierIds = new List<Guid>();
foreach (SupplierRow sr in suppliers)
{
supplierIds.Add(sr.Id);
}
var users = Context.Users.AsNoTracking()
.Where(e => supplierIds.Contains(e.SupplierId.Value))
.Select(e => new UserRow
{
Id = e.Id,
FullName = e.FullName,
Email = e.Email,
Name = e.Name,
Status = e.Status,
Role = e.Role,
SupplierId = e.SupplierId.Value
}).ToList();
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in suppliers)
{
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
return PartialView("_Grid", suppliers);
}
but when I try to debug my project I get some exception here
What's wrong? How can I fix that?
Your Users list are not initialized. Create a new list before accessing it Users = new List<UserRow>(); You can change the SupplierRow class:
public class SupplierRow {
private List<UserRow> users = new List<UserRow>();
public List<UserRow> Users
{
get { return users; }
set { users = value; }
}
...
}
or in the constructor:
public class SupplierRow
{
public SupplierRow()
{
Users = new List<UserRow>();
}
public List<UserRow> Users { get; set; }
...
}
or before accessing it:
foreach (UserRow ur in users)
{
foreach (SupplierRow sr in suppliers)
{
sr.Users = new List<UserRow>();
if (ur.SupplierId == sr.Id)
{
sr.Users.Add(ur);
}
}
}
or you can just use linq:
foreach (SupplierRow sr in suppliers)
{
sr.Users = users.Where(user => user.SupplierId == sr.Id);
}
return PartialView("_Grid", suppliers);