ASP.NET MVC5 Display data to user with specific selected data"Branch" - c#

I have table with the next columns
Id,Name,A_Status,BranchName.
Would be that expendiently to achive, with the next method, i described bellow?
Column branch has 25 different names. So, i want to create a page, with 25 titles of branch(and for each, create his own cshtml page), where user can enter and view data of that specific branch, he has chosen. On each of those pages specific permissions, not all users can enter and view them.
I decided to achive it with the next code.
My controller
public ActionResult A_Branch ()
{
string query = "SELECT BranchName,Name, MAX(A_STATUS) AS A_Status "
+ "FROM Students "
+ "WHERE BranchName= '1_Branch' "
+ "GROUP BY BranchName,Name";
IEnumerable<EnrollmentStudentGroup> data = db.Database.SqlQuery<EnrollmentStudentGroup>(query);
return View(data.ToList());
}
And the next actionresult which i'm going to create 23 times more.
public ActionResult B_Branch ()
{
string query = "SELECT BranchName,Name, MAX(A_STATUS) AS A_Status "
+ "FROM Students "
+ "WHERE BranchName= '2_Branch' "
+ "GROUP BY BranchName,Name";
IEnumerable<EnrollmentStudentGroup> data = db.Database.SqlQuery<EnrollmentStudentGroup>(query);
return View(data.ToList());
}
My 2 models;
public class Student : BaseEntity
{
public int Id { get; set; }
public string BranchName { get; set; }
public string Name { get; set; }
public int A_Status { get; set; }
}
public class EnrollmentStudentGroup
{
public string BranchName { get; set; }
public string Name { get; set; }
public int A_Status { get; set; }
public IEnumerable<EnrollmentStudentGroup> StudentCollection { get; set; }
}
and my Model
public class Model
{
public List<Student> Students { get; set; }
public List<EnrollmentStudentGroup> EnrollmentStudentGroup { get; set; }
}
My newest controller ( after " .select " he is giving me errors )
[HttpGet]
public ActionResult TestNew(string branchname)
{
// check stuff like permissions
var db = new MovieContext();
var model = new Model();
var students = db.Student
.Where(x => x.BranchName == branchname)
.GroupBy(x => new { x.BranchName, x.Name, x.Currency, x.NoCart, x.NoAccount })
.Select(x => new
{
BranchName = x.FirstOrDefault().BranchName,
Name = x.FirstOrDefault().Name,
A_Status = x.Max(p => p.A_Status),
Currency = x.FirstOrDefault().Currency,
NoCart = x.FirstOrDefault().NoCart,
NoAccount = x.FirstOrDefault().NoAccount
}).ToList();
foreach (var item in students)
{
model.Students.Add(new Student
{
A_Status = item.A_Status,
BranchName = item.BranchName,
Name = item.Name,
NoAccount = item.NoAccount,
NoCart = item.NoCart,
Currency = item.Currency
});
}
return View(model);
}
Now that error, i updated my model and view(cshtml) by your answer.
My view(cshtml)
#model Tessa.Models.Model
#{
ViewBag.Title = "BranchView";
}
<h2>BranchView</h2>
#foreach (var item in Model.Students)
{
<p>#item.Name</p>
<p>#item.A_Status</p>
<p>#item.BranchName</p>
<p>#item.NoAccount</p>
<p>#item.NoCart</p>
<p>#item.Currency</p>
}

As in the comments wrote you dont have to do this for every single branch. Here is a solutions which may help you
Your Controller
public ActionResult Branch(string branchname)
{
var db = new ApplicationDbContext();
var model = new Model();
var students = db.Students
.Where(x => x.BranchName == branchname)
.GroupBy(x => new { x.BranchName, x.Name, x.Currency, x.NoCart, x.NoAccount })
.Select(x => new
{
BranchName = x.FirstOrDefault().BranchName,
Name = x.FirstOrDefault().Name,
A_Status = x.Max(p => p.A_Status),
Currency = x.FirstOrDefault().Currency,
NoCart = x.FirstOrDefault().NoCart,
NoAccount = x.FirstOrDefault().NoAccount
}).ToList();
foreach (var item in students)
{
model.Students.Add(new Student
{
A_Status = item.A_Status,
BranchName = item.BranchName,
Name = item.Name,
NoAccount = item.NoAccount,
NoCart = item.NoCart,
Currency = item.Currency
});
}
return View(model);
}
So you only pass the branchname to the controller. Her are severale diffrent ways to do this.
Its good practice to have a model to pass to a view.
public class Model
{
public List<Student> Students { get; set; }
//Some other propertys
public Model()
{
Students = new List<Student>();
}
}
And finialy you can write your view like this
#model TestApp.Models.Model
#{
ViewBag.Title = "BranchView";
}
<h2>BranchView</h2>
#foreach (var item in Model.Students)
{
<p>#item.Name</p>
<p>#item.A_Status</p>
<p>#item.Branchname</p>
<p>#item.NoAccount</p>
<p>#item.NoCart</p>
<p>#item.Currency</p>
}
In the foreach-loop you can do normal html stuff. This will done for every element in your list.
I hope this help you.

Related

Microsoft.AspNetCore.Mvc.Razor.RazorPage<TModel>.Model.get returned null.Exception.What's the issue?I cant find it

Its crashing on my CardDetailsView,the Details IActionResult in my CardsController
CardDetailsView-
public class CardDetailsViewModel
{
public string Id { get; set; }
public string Title { get; set; }
public string ImageUrl { get; set; }
public string Destination { get; set; }
public string Model { get; set; }
public string SNumber { get; set; }
public string QNumber { get; set; }
}
CardDetailsView-
#model CardDetailsViewModel
#{ ViewBag.Title = "Details"; }
Card Details
Title
Destination
Model
SNumber
QNumber
Details
CardsController-
public class CardsController : Controller
{
public readonly DigitalCardsDbContext data;
public CardsController(DigitalCardsDbContext data)
{
this.data = data;
}
public IActionResult Add() => View();
[HttpPost]
public IActionResult Add(CardAddViewModel card)
{
if(!ModelState.IsValid)
{
return View(card);
}
var cardd = new Card
{
Title = card.Title,
ImageUrl = card.ImageUrl,
Destination = card.Destination,
Receiver = card.Receiver,
Model = card.Model,
UserFullName = card.UserFullName,
SNumber = card.SNumber,
QNumber = card.QNumber,
PublicView = card.PublicView
};
this.data.Cards.Add(cardd);
this.data.SaveChanges();
return RedirectToAction("All","Cards");
}
public IActionResult All()
{
var cards = this.data.Cards
.Where(c => c.PublicView == true).ToList();
var usern = User.Identity.Name;
if(usern!=this.User.Identity.Name)
{
return BadRequest();
}
var cardsl = cards
.Select(c => new CardAllViewModel
{
Id = c.Id,
Title = c.Title,
ImageUrl = c.ImageUrl,
Destination = c.Destination,
SNumber = c.SNumber,
QNumber = c.QNumber
})
.ToList();
return View(cardsl);
}
public IActionResult Details(string cardId)
{
var card = this.data.Cards.Where(c => c.Id == cardId)
.Select(c => new CardDetailsViewModel
{
Id = c.Id,
ImageUrl = c.ImageUrl,
Title = c.Title,
Destination = c.Destination,
Model = c.Model,
SNumber = c.SNumber,
QNumber = c.QNumber
})
.SingleOrDefault();
return View(card);
}
The code is crashing on my View,on every div class,Title,ImageUrl,Etc.The exception is Microsoft.AspNetCore.Mvc.Razor.RazorPage.Model.get returned null.
Here is snap-Error
Please verify the value in the image [url] it looks like that could be the reason.

How to group by List<object> ViewModel in view

I want to group by vitaminlist, but it's not working.
My Model
public class SearchModel
{
public List<tbbesin> besinlist { get; set; }
public List<tbvitamin> vitaminliste { get; set; }
public List<tbmineral> mineralliste { get; set; }
}
My Controller
public ActionResult ara(BesinViewModel model)
{
var listegetir = model.besinler.Split(',');
List<tbbesin> besinliste = new List<tbbesin>();
List<tbmineral> minerallist = new List<tbmineral>();
List<tbvitamin> vitaminlist = new List<tbvitamin>();
SearchModel modelden = new SearchModel();
foreach (var item in listegetir)
{
var ID = int.Parse(item);
var besin = db.tbbesin.FirstOrDefault(x => x.besinid == ID);
var mineral = db.tbmineral.FirstOrDefault(x => x.besinid == ID);
var vitamin = db.tbvitamin.FirstOrDefault(x => x.besinid == ID);
vitaminlist.Add(vitamin);
minerallist.Add(mineral);
besinliste.Add(besin);
}
modelden.besinlist = besinliste.ToList();
modelden.mineralliste = minerallist.ToList();
modelden.vitaminliste = vitaminlist.ToList();
return View(modelden);
}
My View
#model WebApplication1.Models.SearchModel
#foreach (var item22 in Model.vitaminliste.
GroupBy(x => x.vitamindetayid).
Select(x=>x.First()).
ToList())
{
#item22.tbvitamindetay.vitaminad
}
I need to group by in view vitaminlist but its not working.
Why ? Can you help me what is a problem there

How to refactor these?

I wonder how to refactor a piece of code like this. It is a method in controller and I'm passing 2 SelectLists to Html via ViewBag.
public async Task<IActionResult> Index()
{
var teacherInfo = context.Teachers.OrderBy(x => x.Id);
IEnumerable<SelectListItem> selectList = from s in teacherInfo
select new SelectListItem
{
Value = s.Id.ToString(),
Text = s.FirstName + " " + s.LastName.ToString()
};
ViewBag.TeacherId = new SelectList(selectList, "Value", "Text");
var studentInfo = context.Students.OrderBy(x => x.Id);
IEnumerable<SelectListItem> selectListStudents = from s in studentInfo
select new SelectListItem
{
Value = s.Id.ToString(),
Text = s.FirstName + " " + s.LastName.ToString()
};
ViewBag.StudentId = new SelectList(selectListStudents, "Value", "Text");
return View();
}
I've tried this but it seems i can't use generic like this because T has no definition for Id and other fields:
private async Task<IEnumerable<SelectListItem>> GetSelectListItem<T>(IOrderedQueryable<T> dbData)
{
IEnumerable<SelectListItem> selectList = from s in dbData
select new SelectListItem
{
Value = s.Id.ToString(),
Text = s.FirstName + " " + s.LastName.ToString()
};
return selectList;
}
Any help would be appreciated
You need to constraint the T to an interface which contains those properties
internal interface IListItem
{
int Id { get; }
string FirstName { get; }
string LastName { get; }
}
Then make your student and teacher implement this interface.
You can create a generic class for Students and Teachers classes to inherit.
public class BaseClassForSelectItems
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Students: BaseClassForSelectItems
{
}
public class Teachers: BaseClassForSelectItems
{
}
public async Task<IActionResult> Index()
{
var teacherInfo = context.Teachers.OrderBy(x => x.Id);
IEnumerable<SelectListItem> selectList = await GetSelectListItem(teacherInfo);
ViewBag.TeacherId = new SelectList(selectList, "Value", "Text");
var studentInfo = context.Students.OrderBy(x => x.Id);
IEnumerable<SelectListItem> selectListStudents = await GetSelectListItem(studentInfo);
ViewBag.StudentId = new SelectList(selectListStudents, "Value", "Text");
return View();
}
private async Task<IEnumerable<SelectListItem>> GetSelectListItem<T>(IOrderedQueryable<T> dbData) where T : BaseClassForSelectItems
{
IEnumerable<SelectListItem> selectList = from s in dbData
select new SelectListItem
{
Value = s.Id.ToString(),
Text = s.FirstName + " " + s.LastName.ToString()
};
return selectList;
}

From a one to many situation how do I get common items in Entity Framework

I just started with Entity Framework and I was having difficulty generating a query for the following situation.
I currently have two model classes Student and Sport. A student can play multiple sports. This is what my models look like
public class DbContext : DbContext
{
public DbContext(): base("name=DbContext")
{
}
public DbSet<Student> MyStudents { get; set; }
public DbSet<Sport> MySports { get; set; }
}
public class Student
{
public List<Sport> Actions { get; set; }
public string Name { get; set; }
}
public class Sport
{
public string SportName { get; set; }
}
My question is how do I get a list of all sports played by all the students? In short I am looking for common sports. So basically in the following case
Student A played Sports : Soccer , Tennis , Bowling
Student B played Sports : Soccer , Tennis ,
Student C played Sport : Tennis
Then only Tennis should be returned
Using the DB schema you've provided you can get the common sports checking sports of each student:
var sports = new[]
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" },
new Sport { SportName = "Bowling" }
};
var students = new[]
{
new Student
{
Name = "Student 1",
Actions = sports
},
new Student
{
Name = "Student 2",
Actions = new[] { sports[0], sports[1] }
},
new Student
{
Name = "Student 3",
Actions = new[] { sports[0] }
}
};
// Or
var sports = context.Sports;
var students = context.Students;
// In case students' sports are objects (as in this sample) you can use such a query:
var commonSports = sports.Where(sport =>
students.All(student => student.Actions.Contains(sport)));
// In case you're going to check the sports by name, this:
var commonSports = sports.Where(sport =>
students.All(student => student.Actions.Any(studSport =>
studSport.SportName == sport.SportName)));
Console.WriteLine($"Comon sports: {string.Join(",", commonSports.Select(i => i.SportName))}");
// To get only names of common sports:
var sportNames = commonSports.Select(i => i.SportName);
Console.Read();
If you use a relational database it would be easier and (as for me) more logical to implement many-to-many relationship as described here:
var context = new DbContext()
var unique = context.MyStudents.SelectMany(student => student.Actions.Select(sport => sport.SportName)).Distinct();
you just do this :
var commonSports = Context.Students.SelectMany(x=>x.Actions).GroupBy(x => x.SportName).Where(x=>x.Count()==items.Count(c=>c.Actions!=null)).Select(x=>x.Key).ToList();
I hope it been helpful .
To achieve this you might want to first set up some kind of model class, this isn't strictly necessary but might make things clearer for you:
public class StudentWithSports()
{
public string Name {get;set;}
public List<string> Sports {get;set;}
}
You can then populate your model from your context:
using(var context = new DbContext())
{
List<StudentWithSports> list = context
.Students
.Include(stu => stu.Actions)
.Select(stu => new StudenWithSports
{
Name = stu.Name,
Sports = stu.Actions.Select(act => act.SportName).ToList()
}).ToList();
}
If you don't want to create a model you could just do:
var list = context
.Students
.Include(stu => stu.Actions)
.Select(stu => new {
Name = stu.Name,
Sports = stu.Actions.Select(act => act.SportName).ToList()
}).ToList();
Which will give you a list of anonymous objects with the same properties.
The essence of my answer is the linq query, but I created a couple of classes to model your EF classes to show it works.
Student student1 = new Student
{
Name = "John",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" },
new Sport { SportName = "Bowling" }
}
};
Student student2 = new Student
{
Name = "Mary",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" },
new Sport { SportName = "Soccer" }
}
};
Student student3 = new Student
{
Name = "Jane",
Actions = new List<Sport>
{
new Sport { SportName = "Tennis" }
}
};
IEnumerable<Student> students = new List<Student>
{
student1,
student2,
student3
};
var query = from s in students
select new
{
s.Name,
Sports = from sp in s.Actions
select sp.SportName
};
var result = query.ToList();
for (int i = 0; i < result.Count(); i++)
{
Console.Write(result[i].Name + " played sports: ");
foreach (var sport in result[i].Sports)
Console.Write(" " + sport);
Console.WriteLine();
}
Well your Db design isn't right because you have many to many relation between MyStudents and MySports tables. You have to add joint table between Students and Sports. You can call it StudentsSports
public class DbContext : DbContext
{
public DbContext(): base("name=DbContext")
{
}
public DbSet<Student> MyStudents { get; set; }
public DbSet<StudentsSport> StudentsSports { get; set; }
public DbSet<Sport> MySports { get; set; }
}
public class Student
{
public int ID { get; set; }
public List<StudentsSport> Actions { get; set; }
public string Name { get; set; }
}
public class Sport
{
public int ID { get; set; }
public string SportName { get; set; }
}
public class StudentsSport
{
public int ID { get; set; }
[ForeignKey(Student)]
public int StudentID { get; set; }
[ForeignKey(Sport)]
public int SportID { get; set; }
}
Then you can just do
var listOfActions = MyStudents.Select(s => s.Actions.Select(a => a.SportID));
var intersection = listOfActions
.Skip(1)
.Aggregate(
new HashSet<T>(listOfActions.First()),
(h, e) => { h.IntersectWith(e); return h; }
);
EDIT:
If you have students without sports then you will always get empty intersection list. If you don't want that then you will have to filter them
var listOfActions = MyStudents.Select(s => s.Actions.Select(a => a.SportID)).Where(c => c.Any());

How to call ArrayList from Controller to view in MVC4?

i want to call Arraylist in view. I will explain my issue clearly.
My Controller Code
public ActionResult customerid()
{
List<Customer> n = (from c in db.Customers where c.IsDeleted == false select c).ToList();
var customertype = string.Empty;
for (var i = 0; i < n.Count; i++)
{
var objCustomerName = n[i].DisplayName;
var objCustomerID = n[i].CustomerID;
var objCusCreatedDate=n[i].CreatedDate;
var objNextDate = objCusCreatedDate.GetValueOrDefault().AddDays(120);
var salescount = (from sc in db.SalesOrders where sc.CustomerID==objCustomerID && sc.CreatedDate >= objCusCreatedDate && sc.CreatedDate<= objNextDate select sc.SalesOrderID).Count();
if (salescount <= 3&& salescount> 0)
{
customertype = "Exisiting Customer";
}
else if (salescount >= 3)
{
customertype = "Potential Customer";
}
else
{
customertype = "New Customer";
}
ArrayList obj = new ArrayList();
{
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
}
var details = obj;
}
return View();
}
My View Model
public class CustomerTypeViewModel
{
public System.Guid CustomerID { get; set; }
public string CustomerName { get; set; }
public DateTime CreatedDate { get; set; }
public string SalesCount { get; set; }
public string CustomerType { get; set; }
}
I want to call this array list in view. How I do that? That is i am generating one view based on controller code I need output same as like which is mentioned in the below image .
Wanted Output
Wanted Output
So i put all the fields (which i going to give as a column in View) in Array list. Now i want to call that Arraylist
obj.Add(new string[] { objCustomerName, customertype, salescount.ToString()});
in view . How I do that? I tried to explain my issue as per my level best. please understand my problem and tell me one solution. I am new to MVC so please help me to solve this problem.
In your controller:
List<CustomerTypeViewModel> obj = new List<CustomerTypeViewModel>();
obj.Add(new CustomerTypeViewModel(){
CustomerName = objCustomerName,
CustomerType = customertype,
SalesCount = salescount.ToString()
});
return View(obj);
In your view
#model IEnumerable<CustomerTypeViewModel>
and display values like this
#if (Model.Any()) {
foreach (var m in Model) {
#Html.DisplayFor(x => m.CustomerName)
#Html.DisplayFor(x => m.CustomerType)
}
}

Categories