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

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);

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

Asp Core, How to create Paging?

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.

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>

How to Change Variable Value in EntityFramework

i'm learning, EntityFramework.
using (YonetimDBEntities YonetimDB = new YonetimDBEntities())
{
var Sorgu = from c in YonetimDB.iletisim
select new {
c.id,
c.FullName,
c.Email,
c.Subject,
c.Date,
c.Status
};
// Status Value 1 or 0
myRepeaterName.DataSource = Sorgu.ToList();
myRepeaterName.DataBind();
}
My c.Status value 1 or 0 , i want control my status value and write in my Repeater Line,
Example
if (c.Status == 1) { c.StatusString = "Active"; }else{ c.StatusString = "Deactive"; }
Can i read and how to write my Repeater Line.
Thanks.
Since you are creating an anonymous type (new {}) you can basically add whatever you want into it.
Try this:
var Sorgu = from c in YonetimDB.iletisim
select new {
c.id,
c.FullName,
c.Email,
c.Subject,
c.Date,
c.Status,
StatusString = c.Status == 1 ? "Active" : "Deactive"
};
A better solution is actually this:
public class sorguModel {
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Subject { get; set; }
public DateTime Date { get; set; }
public bool Status { get; set; }
public string StatusText {
get{
return this.Status == 1 ? "Active" : "Deactive";
}
}
}
var sorguList = YonetimDB.iletisim
.select( i => new sorguModel {
Id = c.id,
FullName = c.FullName,
Email = c.Email,
Subject = c.Subject,
Date = c.Date, // ASSUMING THE DATE IS A PROPER DATE FORMAT
Status = c.Status})
.ToList();

Entity Framework : adding record with related data

I have a very simple Situation with 2 tables
public class Movie
{
[Key]
public Guid ID { get; set; }
public string Name { get; set; }
public byte[] Hash { get; set; }
public int GenreID{ get; set; }
[ForeignKey("GenreID")]
public virtual Genre genre{ get; set; }
}
and
public class Genre
{
public int ID { get; set; }
public string Name { get; set; }
}
Now, in an import sequence I want to create new movies and link the Genre with the existing entries in the Genre table or create new Genre entries if they don't exist.
Movie m = new Movie();
m.ID = Guid.NewGuid();
IndexerContext db = new IndexerContext();
var genre = db.Genre.Where(g => g.Name== genreValue).FirstOrDefault();
if(genre!= null)
{
m.GenreID= genre.GenreID;
}
else
{
genre= new Genre();
genre.Name = genreValue;
db.Genres.Add(genre);
var genreCreated= db.Genre.Where(g => g.Name== genreValue).FirstOrDefault();
m.GenreID= genreCreated.GenreID;
}
Now the problem is, it doesn't work. The last line fails because genreCreated is null.
Plus I think I must doing it wrong - it can't be that difficult in Entity Framework.
can anyone help me?
db.Genres.Add(genre);
This does not send insert statement to database - this instructs entity framework that new record should be inserted when saving changes. Genre will be saved (and created id available) after you call db.SaveChanges(); As for now, you do not have save call, so genreCreated is null.
In your situation - fix is simple, you do not need to select genreCreated from db. Just setting m.Genre to new value should do the job
Movie m = new Movie();
m.ID = Guid.NewGuid();
IndexerContext db = new IndexerContext();
var genre = db.Genre.Where(g => g.Name== genreValue).FirstOrDefault();
if(genre! = null)
{
m.GenreID = genre.GenreID;
}
else
{
genre = new Genre();
genre.Name = genreValue;
m.Genre = genre;
}
db.SaveChanges(); //m.GenreID will automatically be set to newly inserted genre
After the add statement you need to save it:
Try
genre= new Genre();
genre.Name = genreValue;
db.Genres.Add(genre);
db.SaveChanges();

Resources