Asp Core, How to create Paging? - asp.net

I want to use PagingList<T>.CreateAsync() to create PagedList in index view but get below error in line var modelPaging = await PagingList<UserListViewModel>.CreateAsync(model, 10, page);:
can not convert from system.collection.Generic.List<> to system.linq.IorderedQueryable<>
my action code :
[HttpGet]
public async Task<IActionResult> Index(int page = 1)
{
List<UserListViewModel> model = new List<UserListViewModel>();
model = _userManager.Users.AsNoTracking().Select(u => new UserListViewModel
{
Id = u.Id,
FullName = u.FirstName + " " + u.LastName,
Email = u.Email
}).OrderBy(u => u.Id).ToList();
var modelPaging = await PagingList<UserListViewModel>.CreateAsync(model, 10, page);
return View(modelPaging);
}
and UserListViewModel Viewmodel:
public class UserListViewModel
{
public string Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string RoleName { get; set; }
}
What changes should I make in my code?
I asked another question on this subject here link

The error is pretty clear that tells you CreateAsync needs IOrderedQueryable but you are giving the data already retrieved from database. You should pass the query itself. Remove ToList;
var query = _userManager.Users.AsNoTracking().Select(u => new UserListViewModel
{
Id = u.Id,
FullName = u.FirstName + " " + u.LastName,
Email = u.Email
}).OrderBy(u => u.Id);
var modelPaging = await PagingList<UserListViewModel>.CreateAsync(query, 10, page);
The main purpose of PagingList apply the pagination directly from database instead of in-memory.

Related

Dynamically Bind Image to Crystal Report from ViewModel and string type Image Property

I have joined 3 tables(Employee,Department,Designation) in a viewmodel. and follow up the BLL,DAL pattern is asp.net.
My problem is I want to generate report of individual employee based on their unique EmployeeId.
Somehow I managed to retrieve information of each employee except their Image. The Image is set to database as ImageLocation
EmployeeReportVM.cs
public class EmployeeReportVM
{
public string Image { get; set; }
public string EmployeeName { get; set; }
public string EmployeeId { get; set; }
public string Department { get; set; }
public string Designation { get; set; }
public string Grade { get; set; }
public string BloodGroup { get; set; }
public string Phone { get; set; }
public string JoiningDate { get; set; }
}
EmployeeDAL.cs
public List<EmployeeReportVM> EmployeeReport(string employeeId)
{
var emp = (from e in db.Employees
join de in db.Designation on e.DesignationId equals de.DesignationId
join dp in db.Department on e.DepartmentId equals dp.DepartmentId
where e.EmployeeId == employeeId
select new EmployeeReportVM
{
Image = e.Image,
EmployeeName = e.FirstName + " " + e.LastName,
EmployeeId = e.EmployeeId,
Department = dp.DepartmentName,
Designation = de.DesignationName,
Phone = e.MobileNo
}).ToList();
return emp;
}
EmployeBLL.cs
EmployeeDAL employeeDal = new EmployeeDAL();
public List<EmployeeReportVM> EmployeeReportVM(string employeeId)
{
var data = employeeDal.EmployeeReport(employeeId);
return data;
}
EmployeeController.cs
EmployeeBLL employeeBll=new EmployeeBLL();EmployeeBLL employeeBll=new EmployeeBLL();
public ActionResult DownloadEmployeeReport(string employeeId)
{
//ApplicationDbContext db = new ApplicationDbContext();
var data = employeeBll.EmployeeReportVM(employeeId);
ReportDocument rd = new ReportDocument();
rd.Load(Path.Combine(Server.MapPath("~/Reports"), "EmployeeReport.rpt"));
rd.SetDataSource(data.Select(c => new
{
Image = c.Image,
EmployeeName = c.EmployeeName,
EmployeeId = c.EmployeeId,
Department = c.Department,
Designation = c.Designation
}).Where(x => x.EmployeeId == employeeId));
//string pathString = Path.Combine(#"D:\Sayeem\Project\NassaHRMS\Content\Images");
Response.Buffer = false;
Response.ClearContent();
Response.ClearHeaders();
rd.PrintOptions.PaperOrientation = CrystalDecisions.Shared.PaperOrientation.Landscape;
rd.PrintOptions.ApplyPageMargins(new CrystalDecisions.Shared.PageMargins(5, 5, 5, 5));
rd.PrintOptions.PaperSize = CrystalDecisions.Shared.PaperSize.PaperA5;
//rd.SetDatabaseLogon("root","", "NassaHRMS", "DESKTOP-PN96TKB");
Stream stream = rd.ExportToStream(CrystalDecisions.Shared.ExportFormatType.PortableDocFormat);
stream.Seek(0, SeekOrigin.Begin);
return File(stream, "application/pdf", "EmployeeDetails.pdf");
}
EmployeeList.cshtml
#using (Html.BeginForm("Edit", "Account", new { id = #item.EmployeeId }, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<a class="btn btn-sm btn-outline-info" target="_blank" href="#Url.Action("DownloadEmployeeReport", "Employee",new { #employeeId = item.EmployeeId})"><i class="fa fa-print" title="Print Card"></i></a>
}
The Location of Crystal Report
enter image description here
Here you are doing everything right i guess. Just some issue in picture2 graphic location. What does your database image column contains ? is it only contains image name like someimage.jpg then your graphic location should be like below.
D:\Sayeem\Project\NassaHRMS\EmployeeImage\ + NassaHRMS_ViewModels_EmployeeReportVM.Image
If it contains full Physical Path like D:\Sayeem\Project\NassaHRMS\EmployeeImage\someimage.jpg then your graphic location should be like below
NassaHRMS_ViewModels_EmployeeReportVM.Image

The parameterized query '(#role nvarchar(5),#count int)StudentProcedure #role,#count OUT' expects the parameter '#count', which was not supplied

//Student Controller
public class Student
{
[Key]
public int StudentId { get; set; }
public string Name { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string Emial { get; set; }
public string Role { get; set; }
}
//StudentConroller (Here I called Stored Procedure)
public class AccountController : Controller
{
public ApplicationDbClass applicationDbClass;
public AccountController()
{
applicationDbClass = new ApplicationDbClass();
}
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(Student student)
{
var v1 = new SqlParameter();
v1.ParameterName = "#role";
v1.SqlDbType = SqlDbType.NVarChar;
v1.Value = "Admin";
var v2 = new SqlParameter();
v2.ParameterName = "#count";
v2.SqlDbType = SqlDbType.Int;
try
{
var result = applicationDbClass.Students.SqlQuery("StudentProcedure #role,#count OUT", v1, v2).ToArray();
}
catch(Exception e)
{
var m = e.Message;
}
return RedirectToAction("Welcome", "Student");
}
}
//Stored procedure
CREATE OR ALTER PROCEDURE StudentProcedure
#role NVARCHAR(30),
#count INT OUTPUT
AS
BEGIN
SELECT #count=COUNT(dbo.Students.Role)
FROM dbo.Students
WHERE Role=#role;
END
//DbContext Class
public class ApplicationDbClass : DbContext
{
public ApplicationDbClass() : base()
{
Database.SetInitializer<ApplicationDbClass>(new DropCreateDatabaseIfModelChanges<ApplicationDbClass>());
}
public DbSet<Student> Students { get; set; }
public DbSet<LogTable> LogTables { get; set; }
}
// Here I am using code first approch to deal with database using entity framework to call the user created stored procedure. If I make some changes on stored procedure it will not refected directly. Please give me any solution to refects the changes.
You can pass parameters in this way also
SqlConnection cnn = new SqlConnection(cnnString);
SqlCommand cmd = new SqlCommand("StudentProcedure", cnn);
cmd.Connection = cnn;
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#role", "Admin");
cmd.Parameters.Add("#count", SqlDbType.Int);
cmd.Parameters["#count"].Direction = ParameterDirection.Output;
string Query = cmd.ExecuteNonQuery().ToString();
Here my goal is to show how to pass normal and output parameter to procedure.
There are two issues here in your code.
You should set the default value for your output parameter. Otherwise C# code will throw an exception if you do not set default value to your output parameter. So your stored procedure should look like this:
ALTER PROCEDURE StudentProcedure
#role NVARCHAR(30),
#count INT = NULL OUTPUT
AS
BEGIN
SELECT #count=COUNT(dbo.Students.Role)
FROM dbo.Students
WHERE Role=#role;
SELECT #count;
END
GO
And the second issue is you've forgot to set Direction of your output parameter:
var sqlParameter_Role = new SqlParameter("#role", "Admin");
var sqlParameter_Count = new SqlParameter();
sqlParameter_Count.ParameterName = "#count";
sqlParameter_Count.SqlDbType = SqlDbType.Int;
sqlParameter_Count.Direction = ParameterDirection.Output;
var result = db.Database
.SqlQuery<ResultForStudentProcedure>("dbo.StudentProcedure #role"
, sqlParameter_Role
, sqlParameter_Count)
.ToList();
public class ResultForStudentProcedure
{
public int Count { get; set; }
}

Integration Testing Forms with Nested Objects

I am using .NET Core with Boilerplate. I'm trying to unit test some new forms that require that I have nested objects with properties. The Integration Tests use AbpAspNetCoreIntegratedTestBase<Startup> which uses an instance of both HttpClient and TestServer. The client has various types of methods at its disposal. There are GetAsync, PostAsync, SendSync and PutAsync methods just to name a few.
I thought I had gotten comfortable with some of the methods and helper methods in this frame work and have been successful thus far. However, I have a form with an Model called Vendor, the Vendor has an Address Model as part of the view model. This is so I can reuse the Address View Model with other items in the application that also require Address(es).
One of the helpers that is used with BoilerPlate is GetUrl<TController>(string actionName, object queryStringParamsAsAnonymousObject) Since this is a Post from a form I'm attempting to use public Task<HttpResponseMessage> PostAsync(string requestUri, HttpContent content) No matter what I'm attempting to do, I'm getting a 400 Bad Request response and my test fails before it even gets inside the controller method. I'm at a loss of how to handle this.
Here are my Models:
VendorViewModel:
[AutoMap(typeof(Domains.Vendor))]
public class VendorViewModel : BaseViewModelEntity
{
[Required]
public string Name { get; set; }
[Required]
public string PointOfContact { get; set; }
[Required]
public string Email { get; set; }
[Required]
public int AddressId { get; set; }
//[Required]
//public string Address1 { get; set; }
//public string Address2 { get; set; }
//public string Address3 { get; set; }
//[Required]
//public string City { get; set; }
//[Required]
//public int State { get; set; }
//[Required]
//public string Zip { get; set; }
//[Required]
//public string Phone { get; set; }
//public string Fax { get; set; }
public AddressViewModel VendorAddress { get; set; }
public VendorViewModel()
{
VendorAddress = new AddressViewModel();
}
public VendorViewModel(VendorDto vendor)
{
Id = vendor.Id;
Name = vendor.Name;
IsActive = vendor.IsActive;
PointOfContact = vendor.PointOfContact;
Email = vendor.Email;
AddressId = vendor.AddressId;
CreatorUserId = vendor.CreatorUserId;
CreationTime = vendor.CreationTime;
DeleterUserId = vendor.DeleterUserId;
DeletionTime = vendor.DeletionTime;
LastModificationTime = vendor.LastModificationTime;
LastModifierUserId = vendor.LastModifierUserId;
//Address1 = vendor.Address.Address1;
//Address2 = vendor.Address.Address2;
//Address3 = vendor.Address.Address3;
//City = vendor.Address.City;
//State = vendor.Address.State;
//Zip = vendor.Address.Zip;
//Phone = vendor.Address.Phone;
//Fax = municipalities.Address.Fax;
VendorAddress = new AddressViewModel()
{
Id = vendor.Address.Id,
Address1 = vendor.Address.Address1,
Address2 = vendor.Address.Address2,
Address3 = vendor.Address.Address3,
City = vendor.Address.City,
State = vendor.Address.State,
Zip = vendor.Address.Zip,
Phone = vendor.Address.Phone,
Fax = vendor.Address.Fax,
CreationTime = vendor.Address.CreationTime,
};
}
}
Address View Model:
public class AddressViewModel : BaseViewModelEntity
{
[Required]
public string Address1 { get; set; }
public string Address2 { get; set; }
public string Address3 { get; set; }
[Required]
public string City { get; set; }
[Required]
public int State { get; set; }
[Required]
public string Zip { get; set; }
[Required]
public string Phone { get; set; }
public string Fax { get; set; }
public AddressViewModel()
{
}
public AddressViewModel(AddressDto address)
{
Id = address.Id;
Address1 = address.Address1;
Address2 = address.Address2;
Address3 = address.Address3;
City = address.City;
State = address.State;
Zip = address.Zip;
Phone = address.Phone;
Fax = address.Phone;
CreatorUserId = address.CreatorUserId;
CreationTime = address.CreationTime;
DeleterUserId = address.DeleterUserId;
DeletionTime = address.DeletionTime;
LastModificationTime = address.LastModificationTime;
LastModifierUserId = address.LastModifierUserId;
}
}
I have my Test set up with xUnit
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var addressViewModel = new AddressViewModel()
{
Address1 = "123 This Way", City = "Arlington", State = 44, Zip = "76001", Phone = "8175555555",
CreationTime = DateTime.Now
};
var viewModelSave = new VenderViewModel()
{
Name = "Controller Test Name",
PointOfContact = "Tom Jerry",
Email = "Tom.Jerry#yolo.com",
CreationTime = DateTime.Now,
LastModificationTime = null,
IsActive = true,
AddressId = 0,
VendorAddress = addressViewModel
//Address1 = "123 This Way",
//City = "Arlington",
//State = 44,
//Zip = "76001",
//Phone = "8175555555"
};
/* This is an attempt to use string interpolation to create querystring parameters */
//var rawData =
// $"?Name={viewModelSave.Name}&Id={viewModelSave.Id}&PointOfContat=${viewModelSave.PointOfContact}&Email={viewModelSave.Email}&CreationTime={DateTime.Now}" +
// $"&LastModificationTime=&IsActive={viewModelSave.IsActive}&AddressId={viewModelSave.AddressId}&VendorAddress.Id={viewModelSave.VendorAddress.Id}&VendorAddress.Address1={viewModelSave.VendorAddress.Address1}" +
// $"&VendorAddress.City={viewModelSave.VendorAddress.City}&VendorAddress.State={viewModelSave.VendorAddress.State}&VendorAddress.Zip={viewModelSave.VendorAddress.Zip}&VendorAddress.Phone={viewModelSave.VendorAddress.Phone}" +
// $"&VendorAddress.CreationTime={DateTime.Now}&VendorAddress.IsActive={viewModelSave.VendorAddress.IsActive}";
/*This is an attempt to create a json object that could be serialize into an object as the "queryStringParamsAsAnonymousObject" that can be used in the GetUrl Helper method below */
var rawData = $"{{'Name':'Controller Test Name','PointOfContact':'Tom Jerry', 'Email': 'Tom.Jerry#yolo.com',"
+ "'CreationTime':'" + DateTime.Now + "','LastModificationTime':'','IsActive' : 'true','AddressId':'0','Address.Address1':'123 This Way',"
+ "'Address.City':'Arlington','Address.State':'44','Address.Zip':'76001','Address.Phone':'8175555556','Address.IsActive':'true'}";
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
var vendorAddress = new
{
viewModelSave.vendorAddress.Id,
viewModelSave.vendorAddress.Address1,
viewModelSave.vendorAddress.City,
viewModelSave.vendorAddress.State,
viewModelSave.vendorAddress.Zip,
viewModelSave.vendorAddress.Phone,
viewModelSave.vendorAddress.IsActive,
viewModelSave.vendorAddress.CreationTime
};
//actually get the url from helper method (with various attempts at creating an anonymousObject directly
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor),
new
{
viewModelSave.Id,
viewModelSave.Name,
viewModelSave.PointOfContact,
viewModelSave.Email,
viewModelSave.CreationTime,
viewModelSave.LastModificationTime,
viewModelSave.IsActive,
viewModelSave.AddressId,
vendorAddress
//VendorAddress_Address1 = vendorAddress.Address1,
//VendorAddress_Id = vendorAddress.Id,
//VendorAddress_City = vendorAddress.City,
//VendorAddress_State = vendorAddress.State,
//VendorAddress_Zip = vendorAddress.Zip,
//VendorAddress_Phone = vendorAddress.Phone,
//VendorAddress_IsActive = vendorAddress.IsActive,
//VendorAddress = new
//{
// viewModelSave.VendorAddress.Id,
// viewModelSave.VendorAddress.Address1,
// viewModelSave.VendorAddress.City,
// viewModelSave.VendorAddress.State,
// viewModelSave.VendorAddress.Zip,
// viewModelSave.VendorAddress.Phone,
// viewModelSave.VendorAddress.IsActive,
// viewModelSave.VendorAddress.CreationTime
//},
//viewModelSave.Address1,
//viewModelSave.City,
//viewModelSave.State,
//viewModelSave.Zip,
//viewModelSave.Phone
}
);
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
var message = new HttpRequestMessage {
Content = content,
Method = HttpMethod.Post,
RequestUri = new Uri("http://localHost" + url)
};
//Act
var response = await PostResponseAsObjectAsync<AjaxResponse>(url, content);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);
}
As I attempt to debug what is happening. I've noticed that the VendorAddress properties that are sent via the test request do not match what the actual form post looks like when parsed in Chrome developer tools. In Chrome I see (example:
PointOfContact:"Tom Jerry"
IsActive:True
VendorAddress.Address1:"123 This Way"
VendorAddress.City: "Arlington")
I cannot get my test data into that same format, therefore its not binding correctly to my view models on post, and thus returns a 400 response and fails the test.
I have gotten it to work if I remove the Address View Model all together and put those properties as properties of the VendorViewModel. However, I would run into the same if not similar issue if I'm attempting to save a collection of objects along with the main view model.
I feel like there has to be a way to submit test form data via integration tests with boilerplate. I just need some missing piece to this puzzle.
The Solution that is working for both Post and Send Requests:
.NET Core has a QueryHelper class that will take a dictionary and a uri string and convert it into a url with querystring parameters. QueryHelpers.AddQueryString(string uri, IDictionary queryString) This is part of Microsoft.AspNetCore.WebUtilities.
Using this method I was able to properly prepare my formData. For a Post Request the Test would look like this
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var rawData = new Dictionary<string, string>(){{ "Id", "0"}, {"Name", "Controller Test Name"}, {"PointOfContact", "Tom Jerry"}
, {"Email", "Tom.Jerry#yolo.comy"}, {"CreationTime", $"{DateTime.Now}"}, {"LastModificationTime", ""}, {"IsActive", "true"}, {"AddressId", "0"}
, {"VendorAddress.Id", "0"}, {"VendorAddress.Address1", "123 This Way"}, {"VendorAddress.City", "Arlington"}, {"VendorAddress.State", "44"}, {"VendorAddress.Zip", "76001"}
, {"VendorAddress.Phone", "8175555555"}, {"VendorAddress.Fax", ""}, {"VendorAddress.IsActive", "true"}, {"VendorAddress.CreationTime", $"{DateTime.Now}"}, {"VendorAddress.LastModificationTime", ""}
};
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
//actually get the url from helper method
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor));
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
//Act
var response = await PostResponseAsObjectAsync<AjaxResponse>(url, content);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);
Send Request Test would look like this
//Arrange
//Add Client Headers so User Auth and Permission Checkers work correctly
Client.DefaultRequestHeaders.Add("my-name", "admin");
Client.DefaultRequestHeaders.Add("my-id", "2");
//set up test data
var rawData = new Dictionary<string, string>(){{ "Id", "0"}, {"Name", "Controller Test Name"}, {"PointOfContact", "Tom Jerry"}
, {"Email", "Tom.Jerry#yolo.comy"}, {"CreationTime", $"{DateTime.Now}"}, {"LastModificationTime", ""}, {"IsActive", "true"}, {"AddressId", "0"}
, {"VendorAddress.Id", "0"}, {"VendorAddress.Address1", "123 This Way"}, {"VendorAddress.City", "Arlington"}, {"VendorAddress.State", "44"}, {"VendorAddress.Zip", "76001"}
, {"VendorAddress.Phone", "8175555555"}, {"VendorAddress.Fax", ""}, {"VendorAddress.IsActive", "true"}, {"VendorAddress.CreationTime", $"{DateTime.Now}"}, {"VendorAddress.LastModificationTime", ""}
};
var jsonData = JsonConvert.DeserializeObject(rawData);
//Serialize ViewModel to send with Post as part of the HttpContent object
var data = JsonConvert.SerializeObject(viewModelSave);
//actually get the url from helper method
var url = GetUrl<VendorController>(nameof(VendorController.SaveVendor));
var content = new StringContent(data, Encoding.UTF8, "application/x-www-form-urlencoded");
var message = new HttpRequestMessage {
Content = content,
Method = HttpMethod.Post,
RequestUri = new Uri("http://localHost" + url)
};
//Act
var response = await SendResponseAsObjectAsync<AjaxResponse>(message);
//Assert
var count = UsingDbContext(context => { return context.Municipalities.Count(x => x.IsActive); });
response.ShouldBeOfType<AjaxResponse>();
response.Result.ShouldNotBeNull();
count.ShouldBe(3);

Asp.net Mvc and Core , How it works SelectListItem

I have user edit problem in my Edit actions.. when it comes to departmentDropdownlist
When I click a user to edit let say he/she belongs to administration, I want then show
administration in dropdownlist and offcourse below that all departments in the same dropdownlist.
But right now when I click Edit It shows me all departments in Id order.. like I want to add a new user.
I have role dropdown list. tha's woking fine. If the user is Employee .. it shows me first Employee then the rest of Role list.. If the user is Admin , then it shows me Admin
then below that the rest of role list. But when it comes to department it shows me the first departmentname which DeptId = 1 and so on. I tried in both Asp.Net Mvc and Core. Here is my EditUser and EditUserViewModel
[HttpGet]
public async Task<IActionResult> EditUser(string id)
{
EditUserViewModel model = new EditUserViewModel();
model.ApplicationRoles = roleManager.Roles.Select(r => new SelectListItem
{
Text = r.Name,
Value = r.Id
}).ToList();
model.DepartmentNames = context.Departments.Select(s => new SelectListItem
{
Text = s.DeptName,
Value = s.DeptId.ToString()
}).ToList();
if (!String.IsNullOrEmpty(id))
{
ApplicationUser user = await userManager.FindByIdAsync(id);
if (user != null)
{
model.Name = user.Name;
model.Email = user.Email;
model.ApplicationRoleId = roleManager.Roles.Single(r => r.Name == userManager.GetRolesAsync(user).Result.Single()).Id;
model.DeptId = context.Departments.Single(r => r.DeptName == context.Sites.....??????); //How to do here
// ViewBag.DeptId = new SelectList(context.Departments, "DeptId", "DeptName", model.DeptId); // Even like this , shows the first id departmentname
}
}
return PartialView("_EditUser", model);
}
My EditUserViewModel
public class EditUserViewModel
{
public string Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public List<SelectListItem> ApplicationRoles { get; set; }
public string ApplicationRoleId { get; set; }
public List<SelectListItem> DepartmentNames { get; set; }
public int DeptId { get; set; } // I have DeptId too in my AspNetUser table
}
Since the User table has DepartmentId, I don't know why you don't assign model.DeptId to it.
So instead of
model.DeptId = context.Departments.Single(r => r.DeptName == context.Sites.....??????);
You can just assign the DepartmentId from the user table, i.e.,
model.DeptId = user.DepartmentId;
On Razor when you build the dropdown using TagHelper, it should select the correct dropdown option value based on the id.
<select class="form-control" asp-for="DeptId" asp-items="DepartmentNames"></select>

Query a Model regarding its ICollection<> asp.net mvc

Using EntityFramework6 Code-First mvc 5 I have the following model:
Course
public class Course
{
public Course()
{
EnrolledStudentsEmails = new HashSet<ApplicationUser>();
}
[Key]
public string Id { get; set; }
public string UserName{ get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<ApplicationUser> EnrolledStudentsEmails { get; set; }
I'm trying to query the following to IPagedList(Courses)
var model =
(from c in db.Courses
where searchTerm == null ||
c.Id.StartsWith(searchTerm) ||
c.Name.StartsWith(searchTerm)
select new
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
UserName = c.UserName
}).AsEnumerable().Select(c => new Course
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
UserName = c.UserName
}).ToPagedList(page, 10);
What should be the type of the ICollection EnrolledStudents if I want to use the AspNetUsers table generated when using user authentication?
The upper LINQ gets me All the courses in the database.
how can I get the courses that example#123.com is enrolled in?
Is it possible using my model? should I change my model?
Knowing that I can access the Email using:
User.Identity.Name
If your existing code works, your models are correct and you just want to filter by a known email, just use your collection:
var emailFilter = "example#123.com";
var model =
(from c in db.Courses
where (searchTerm == null ||
c.Id.StartsWith(searchTerm) ||
c.Name.StartsWith(searchTerm)) &&
c.EnrolledStudentsEmails.Any(e => e.Email == emailFilter)
select new
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
UserName = c.UserName
}).AsEnumerable().Select(c => new Course
{
Id = c.Id,
Name = c.Name,
Description = c.Description,
UserName = c.UserName
}).ToPagedList(page, 10);

Resources