Count duplicates in C# MVC3 with View - c#

I need a help of displaying the view of comodities, by excluding the duplicate, but adding quantity to the count
E.g.
Name ComodityModel count SellerName
Iphone 3gs 1 Neal
Iphone 4g 1 Jane
Iphone 3gs 1 Neal
Iphone 3gs 1 Jane
Output should be
Name ComodityModel count SellerName
Iphone 3gs 2 Neal
Iphone 4g 1 Jane
Iphone 3gs 1 Jane
I need to filter it by Comodity model and SellerName. I have database and model Comodity
public class Comodity
{
public int ID { get; set; }
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Date is required")]
//[DisplayFormat(DataFormatString = "{0:d}")]
[DataType(DataType.Date)]
public DateTime ? RegisterDate { get; set; }
[Required(ErrorMessage = "Comodity Model must be specified")]
public string ComodityModel { get; set; }
[Required(ErrorMessage = "Color must be specified")]
[StringLength(15)]
public string Color { get; set; }
[Required(ErrorMessage = "Price Required")]
[Range(1, 1000, ErrorMessage = "Price must be between $1 and $100")]
[DisplayFormat(DataFormatString = "{0:c}")]
public decimal Price { get; set; }
[Required(ErrorMessage = "Seller name must be specified")]
[StringLength(15)]
public string SellerName { get; set; }
public int CountCom { get; set; }
}
public class ComodityDBContext : DbContext
{
public DbSet<Comodity> Comodities { get; set; }
}
and Controller where I defined Actionresult MyView
public ActionResult MyView(DateTime? startDate, DateTime? endDate, string comModel, string searchString)
{
// if (string.IsNullOrEmpty(comModel))
// {
// return View(comodities);
// }
// else
// {
// return View(comodities.Where(x => x.ComodityModel == comModel));
// }
DateTime dtNow;
dtNow = DateTime.Today;
if (!startDate.HasValue)
{
startDate = new DateTime(dtNow.Year, dtNow.Month, 1);
endDate = startDate.Value.AddMonths(1).AddDays(-1);
}
if (startDate.HasValue && !endDate.HasValue)
{
endDate = (new DateTime(startDate.Value.Year, startDate.Value.Month, 1)).AddMonths(1).AddDays(-1);
}
ViewBag.startDate = startDate.Value.ToShortDateString();
ViewBag.endDate = endDate.Value.ToShortDateString();
var viewDate = from r in db.Comodities
where r.RegisterDate >= startDate.Value && r.RegisterDate <= endDate.Value == true
// orderby r.RegisterDate
select r.RegisterDate;
var SelectListName = new List<string>();
var SelectNameQry = from m in db.Comodities
select m.SellerName;
SelectListName.AddRange(SelectNameQry.Distinct());
ViewBag.searchString = new SelectList(SelectListName);
var comModelLst = new List<string>();
var comModelQry = from d in db.Comodities
orderby d.ComodityModel
select d.ComodityModel;
comModelLst.AddRange(comModelQry.Distinct());
ViewBag.comModel = new SelectList(comModelLst);
var comodities = from m in db.Comodities
select m;
IDictionary<string, IList<string>> dict = new Dictionary<string, IList<string>>();
var queryC = from c in db.Comodities
group c by c.ComodityModel into g
where g.Count() > 1
select new { ComodityModel = g.Key, CCount = g.Count() };
foreach (var item in queryC)
{ // comodities = comodities.Where(item => item.Name && item => item.CCount);
//View("", item.ComodityModel, item.CCount);
// ViewBag(item.ComodityModel, item.CCount);
String key = item.ComodityModel;
if (dict.ContainsKey(key))
{
// add the class name into an existing "string" collection
dict[key].Add(item.ComodityModel);
}
else
{
// instantiate a new "string" collection and add the class name.
dict[key] = new List<string> { item.ComodityModel };
}
int maxCourseCount = 0;
foreach (var k in dict.Keys)
{
int valueCount = dict[k].Count;
if (valueCount > maxCourseCount)
maxCourseCount = valueCount;
}
}
if (!String.IsNullOrEmpty(searchString))
{
comodities = comodities.Where(s => s.SellerName.Contains(searchString));
}
if (startDate.HasValue && endDate.HasValue)
{
comodities = comodities.Where(r => r.RegisterDate >= startDate.Value && r.RegisterDate <= endDate.Value);
}
if (string.IsNullOrEmpty(comModel))
{
return View(comodities);
}
else
{
return View(comodities.Where(x => x.ComodityModel == comModel));
}
}
I am new in MVC and have no idea how to count and make view. Please, help. Also, is there some suggestion about date picking. It is showing incorrectly. I assume that it only comparing the day, not whole day-month-year. Thanks in advance
Finally MyView
#model IEnumerable<SaleCenter.Models.Comodity>
#{
ViewBag.Title = "total";
}
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
<h2>total</h2>
<p>
#using (Html.BeginForm()){
<p> startdate:#Html.TextBox("startDate", null, new { #class = "datePicker" })
enddate : #Html.TextBox("endDate", null, new { #class = "datePicker" }) </p>
<p> model: #Html.DropDownList("comModel", "All")
seller: #Html.DropDownList("SearchString", "All")
<input type="submit" value="Total" /></p>
}
</p>
<table>
<tr>
<th>
product name
</th>
<th>
Model
</th>
<th>
seller
</th>
<th>
quantity
</th>
<th>
graphic
</th>
</tr>
#foreach (var item in Model)
{
int w = (int)(2000 * item.CountCom / 100);
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.ComodityModel)
</td>
<td>
#Html.DisplayFor(modelItem => item.SellerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountCom)
</td>
<td>
<img src="#Url.Content("~/Content/Images/graph.gif")" width="#w.ToString()px" height="6px" alt="" />
</td>
</tr>
}
</table>
<script type="text/javascript">
$(document).ready(function () {
$('.datePicker').datepicker({ firstDay: 1, dateFormat: 'dd.mm.yy', showOn: 'button',
buttonImage: '/Content/images/calendar.gif',
duration: 0
});
});
</script>

For showing the commodity and it's count in the view. Quick way it to create a anonymous object from your comodities by grouping with name and get it's count. Return this anonymous object as the model to the view.
Better approach is to create ViewModel specific to this purpose, so that you could create a tightly bound view.

Here is a method to plop into your ComodityController.cs file:
private int getComodityCount(string param_Name, string param_ComodityModel, string param_SellerName)
{
return db.Comodity.Where(x => x.Name == param_Name && x.ComodityModel == param_ComodityModel && x.SellerName == param_SellerName).Count();
}
Now, to get the number of duplicates within the Collection of Comodity you call:
int count = getComodityCount("iPhone","3gs","Neal");
What's more, if you change the privacy setting from private to public, you can even call the method from your view like this:
Here is the method changed to public:
public int getComodityCount(string param_Name, string param_ComodityModel, string param_SellerName)
{
return db.Comodity.Where(x => x.Name == param_Name && x.ComodityModel == param_ComodityModel && x.SellerName == param_SellerName).Count();
}
and here is the code for your View:
#{
int count = new ComodityController().getComodityCount("iPhone","3gs","Neal");
}
I hope this helps. The Where(linq) method is REALLY handy for database querying.

Related

How to search between two Dates

I have View page rendered with two outside pages included (#{Html.RenderAction) in One.
All 3 pages have one controller. By default i take all data from MSSQL Database and i have result. Now i need to Filter results by Date, and to take results between some dates.
Here is HTML Code of Search form:
#using (Html.BeginForm("Reporti", "Reporti", null, FormMethod.Get))
{
<table border="0" cellspacing="5" cellpadding="5">
<tbody>
<tr>
<td>Od Datum:</td>
<td><input type="text" id="datumOD" name="datumOD" class="datumOD"></td>
</tr>
<tr>
<td>Do Datum:</td>
<td><input type="text" id="max" name="datumDO" class="datumDO"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Baraj" /></td>
</tr>
</tbody>
</table>
}
Url of page is:h**p://localhost:41777/Reporti/Reporti
After click Search Button i have this URL
h**p://localhost:41777/Reporti/Reporti?datumOD=01.03.2017&datumDO=02.03.2017
Here is code of controller
public ActionResult Reporti(string filter, DateTime? datumOD, DateTime? datumDO)
{
Session["invoiceFrom"] = datumOD;
Session["invoiceTo"] = datumDO;
return View();
}
public ActionResult reportIZ(DateTime? datumOD, DateTime? datumDO)
{
var smetkis = db.smetkis.Include(s => s.firmi);
return View(smetkis.ToList());
}
public ActionResult Report(DateTime? datumOD, DateTime? datumDO)
{
var ponudis = db.ponudis.Include(s => s.ponudaDets).Where(x => x.odobreno);
return View(ponudis.ToList());
}
My question is, how to implement code in public ActionResult Reporti to filter result between dates.
Just add another condition:
public ActionResult Reporti(DateTime? datumOD, DateTime? datumDO)
{
var ponudis = db.ponudis.Include(s => s.ponudaDets).AsQueryable();
if(datumOD.HasValue) //If we have date - add condition
ponudis = ponudis.Where(x => x.odobreno >= datumOD);
if(datumDO.HasValue) //If we have date - add condition
ponudis = ponudis.Where(x => x.odobreno <= datumDO);
return View(ponudis.ToList());
}
If you need to get data from 2 tables at once you should use Union. But if your tables have different structure you should create separate class like RowViewModel. like this:
public class RowViewModel
{
public int Id {get; set;}
public int DateTime? Odobreno {get; set;}
//your other properties
}
And then in your controller:
public ActionResult Reporti(DateTime? datumOD, DateTime? datumDO)
{
var ponudis = db.ponudis.Include(s => s.ponudaDets).AsQueryable();
var smetkis = db.smetkis.Include(s => s.firmi).AsQueryable();
if(datumOD.HasValue) //If we have date - add condition
{
smetkis = smetkis.Where(x => x.odobreno >= datumOD);
ponudis = ponudis.Where(x => x.odobreno >= datumOD);
}
if(datumDO.HasValue) //If we have date - add condition
{
smetkis = smetkis.Where(x => x.odobreno >= datumOD);
ponudis = ponudis.Where(x => x.odobreno <= datumDO);
}
var res = smetkis.Select(x => new RowViewModel
{
Id = x.ID,
Odobreno = x.odobreno
//other properties if you need
}).Union(ponudis.Select(x => new RowViewModel //note Union
{
Id = x.ID,
Odobreno = x.odobreno
//other properties if you need
}));
return View(res);
}

MVC 4 Passing a list from a view to a controller

I'm new to MVC ASP and would need your assistance.
I would like to pass a list from a view to controller but each time I submit my form, the list is empty (null) in the controller.
Here is my model:
namespace ArcheryComp.Models
{
[MetadataType(typeof(Participe))]
public class Participe
{
[Required]
[Display(Name = "Id Archer")]
public int idArcher { get; set; }
[Required]
[Display(Name = "Id Tournoi")]
public int IdTournament { get; set; }
[Required]
[Display(Name = "Division")]
public int division { get; set; }
[Required]
[Display(Name = "Categorie")]
public string categorie { get; set; }
[Required]
[Display(Name = "Score 1")]
public int ArchScore1 { get; set; }
[Display(Name = "X")]
public int ArchScore1_X_6 { get; set; }
[Display(Name = "10")]
public int ArchScore1_10_5 { get; set; }
[Required]
[Display(Name = "Score 2")]
public int ArchScore2 { get; set; }
[Display(Name = "X")]
public int ArchScore2_X_6 { get; set; }
[Display(Name = "10")]
public int ArchScore2_10_5 { get; set; }
[Required]
[Display(Name = "Total")]
public int ArchTotalScore { get; set; }
[Display(Name = "Total X")]
public int ArchTotalScore_X_6 { get; set; }
[Display(Name = "Total 10")]
public int ArchTotalScore_10_5 { get; set; }
public List<Participe> liste { get; set; }
}
}
Here is my controller:
namespace ArcheryComp.Controllers
{
public class ParticipeController : Controller
{
private ArcheryCompEntities db = new ArcheryCompEntities();
......
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult EncodeResult(IList<Participe> parti)
{
foreach (Participe item in parti)
{
var data = from part in db.Participe
where part.IdArcher == item.IdArcher && part.IdTournament == item.IdTournament
select part;
item.ArchScore1 = item.ArchScore1;
item.ArchScore2 = item.ArchScore2;
item.ArchTotalScore = item.ArchTotalScore;
}
And here is my view :
#model List<ArcheryComp.Participe>
#{
ViewBag.Title = "EncodeResult";
}
<h2>Encoder Resultats</h2>
#using (Html.BeginForm("EncodeResult","Participe",FormMethod.Post))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(false)
<table>
<tr>
<th>
#Html.LabelFor(model => Model[0].Archers.Nom)
</th>
<th>
#Html.LabelFor(model => Model[0].Archers.Prenom)
</th>
<th>
#Html.LabelFor(model => Model[0].Divisions.DivDescription)
</th>
<th>
#Html.LabelFor(model => Model[0].Categorie)
</th>
<th>
#Html.LabelFor(model => Model[0].ArchScore1, new {style = "width: 10px;"})
</th>
<th>
#Html.LabelFor(model => Model[0].ArchScore2, new {style = "width: 10px;"})
</th>
<th>
#Html.LabelFor(model => Model[0].ArchTotalScore, new {style = "width: 10px;"})
</th>
</tr>
#for(int i = 0; i < Model.Count() ; i++)
{
<tr>
<td>
#Html.TextBox("archers["+#i+"].IdArcher", Model[i].Archers.Nom)
#Html.ValidationMessageFor(x => x[i].IdArcher)
</td>
<td>
#Html.TextBox("archers["+#i+"].Prenom", Model[i].Archers.Prenom)
</td>
<td>
#Html.TextBox("archers["+#i+"].Division", Model[i].Divisions.DivDescription)
#Html.ValidationMessageFor(x => x[i].Divisions.Id)
</td>
<td>
#Html.TextBox("archers["+#i+"].Categorie", Model[i].Categorie)
#Html.ValidationMessageFor(x => x[i].Categorie)
</td>
<td>
#Html.TextBox("suma["+#i+"]", Model[i].ArchScore1, new{ #onchange = "updatesum()"})
#Html.ValidationMessageFor(x => x[i].ArchScore1)
</td>
<td>>
#Html.TextBox("sumb["+#i+"]", Model[i].ArchScore2, new { #onchange = "updatesum()" })
#Html.ValidationMessageFor(x => x[i].ArchScore2)
</td>
<td>
#Html.TextBox("sumt["+#i+"]", Model[i].ArchTotalScore, new { #onchange = "updatesum()" })
#Html.ValidationMessageFor(x => x[i].ArchTotalScore)
</td>
</tr>
}
</table>
<p>
<input type="submit" value="Save" />
</p>
}
Can you please help sort this out ?
Many thanks in advance !!!
Your use of #Html.TextBox() where you give the input a name that has no relationship whatsoever to your model properties and means that you cannot bind to a collection when you submit.
For example you have a property string categorie which means that the name of the input would need to be name="[0].categorie, yet you create the input with name="archers[0].Categorie". Always use the strongly typed html helper (as you have done with ValidationMessageFor()
#Html.TextBoxFor(x => x[i].Categorie)
#Html.ValidationMessageFor(x => x[i].Categorie)
Side note: In your table headers it should be
<td>#Html.DisplayNameFor(m => m.Categorie)</td>
not #Html.LabelFor(). A <label> is a html accessibility element - clicking on it sets focus to the associated control, which in this case makes no sense since you have a table containing multiple controls for each property.
I got it and it works thanks :)
Nevertheless I still have a small question, I use the following (updatesum()) javascript to dynamically calculate in the field the sum of the archer's score in my view:
<td>
#Html.TextBox("suma["+#i+"]", Model[i].ArchScore1, new{ #onchange = "updatesum()"})
#Html.ValidationMessageFor(x => x[i].ArchScore1)
</td>
<td>>
#Html.TextBox("sumb["+#i+"]", Model[i].ArchScore2, new { #onchange = "updatesum()" })
#Html.ValidationMessageFor(x => x[i].ArchScore2)
</td>
<td>
#Html.TextBox("sumt["+#i+"]", Model[i].ArchTot`enter code here`alScore, new { #onchange = "updatesum()" })
#Html.TextBoxFor(x=>x[i].ArchTotalScore)
#Html.ValidationMessageFor(x => x[i].ArchTotalScore)
</td>
<script type="text/javascript">
function updatesum() {
for (i = 0; i < 15; i++) {
var sua = "suma_" + i + "_";
var sub = "sumb_" + i + "_";
var sut = "sumt_" + i + "_";
suma = document.getElementById(sua).value;
sumb = document.getElementById(sub).value;
sum = (suma - 0) + (sumb - 0);
document.getElementById(sut).value = sum;
}
}
</script>
Do you know if it is feasible to add the result of this javascript function into the TextBoxFor?

Display data based on year and week number

I am developing an application where the administrator types a Datetime as searching terms to match stamp dates in the database.
I need to change it so the search criteria can be based on year and week number. The scenario is the user enter year and week number in the GetWeekStamp View, which after they post redirects to Stampings view where they display the data based on the entered year and week number.
Model 1:
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Aviato.Models
{
public partial class Stamping
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int UserId { get; set; }
[Required]
[DataType(DataType.DateTime)]
public DateTime Timestamp { get; set; }
[Required]
[StringLength(3)]
public string StampingType { get; set; }
public virtual User User { get; set; }
}
}
Model 2:
using System;
using System.Collections.Generic;
using Aviato.Models;
namespace Aviato.ViewModel
{
public class StampingModel
{
public List<Stamping> Stampings { get; set; }
public DateTime Timestamp { get; set; }
}
}
View (GetWeekStamp):
#model Aviato.Models.Stamping
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h1>Ange Datum</h1>
<p>(ÅÅÅÅ-MM--DD)</p>
#Html.EditorFor(model => model.Timestamp, new { htmlAttributes = new { #class = "form-control" } })
<br/>
<br />
<input type="submit" value="Välj" class="btn btn-default">
<br />
<br />
<div>
#Html.ActionLink("Tillbaka", "Index")
</div>
}
View(Stampings)
#model Aviato.ViewModel.StampingModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h2>Instämplingar</h2>
<p>Du har valt: #Model.Timestamp.Year-#Model.Timestamp.Month-#Model.Timestamp.Day</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.Stampings[0].Timestamp)
</th>
<th>
#Html.DisplayNameFor(model => model.Stampings[0].StampingType)
</th>
</tr>
#foreach (var item in Model.Stampings)
{
<tr>
<td>
#Html.DisplayFor(model => item.Timestamp)
</td>
<td>
#Html.DisplayFor(model => item.StampingType)
</td>
</tr>
}
</table>
<p>
#Html.ActionLink("Tillbaka", "GetWeekStamp")
</p>
}
Controller:
public ActionResult GetWeekStamp()
{
return View();
}
[HttpPost]
public ActionResult GetWeekStamp(Stamping model)
{
return RedirectToAction("Stampings", new { model.Timestamp });
}
public ActionResult Stampings(Stamping model)
{
var startTime = model.Timestamp;
var endTime = model.Timestamp.AddDays(1);
var userId = (int)Session["userId"];
var stampings = _db.Stampings.Where(s => s.Timestamp >= startTime && s.Timestamp <= endTime)
.Where(s => s.UserId == userId).ToList();
var stampingModel = new StampingModel();
stampingModel.Stampings = stampings;
stampingModel.Timestamp = model.Timestamp;
return View(stampingModel);
}
I have found this Converter class here in Stack, but I am not sure what to do with it...
Class:
public class DateConverter
{
public static DateTime FirstDateOfWeek(int year, int weekOfYear)
{
var jan1 = new DateTime(year, 1, 1);
var daysOffset = DayOfWeek.Thursday - jan1.DayOfWeek;
var firstThursday = jan1.AddDays(daysOffset);
var cal = CultureInfo.CurrentCulture.Calendar;
var firstWeek = cal.GetWeekOfYear(firstThursday, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
var weekNum = weekOfYear;
if (firstWeek <= 1)
{
weekNum -= 1;
}
var result = firstThursday.AddDays(weekNum * 7);
return result.AddDays(-3);
}
}
you can get week number using extension method like this:
public static int GetWeekNumber(this DateTime dateTime)
{
CultureInfo currentCulture = CultureInfo.CurrentCulture;
return currentCulture.Calendar.GetWeekOfYear(dateTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
}
to get a year from DateTime just use:
var datetime = DateTime.Now; //i'm using Now, but you can use the one from Timestamp ...
var year = datetime.Year;
You need to create a model for GetWeekStamp view
using System;
using System.Collections.Generic;
using Aviato.Models;
namespace Aviato.ViewModel
{
public class GetWeekStampModel
{
public int Year { get; set; }
public int WeekNo { get; set; }
}
}
then change GetWeekStamp view code to this so user can enter the year and week number
#model Aviato.ViewModel.GetWeekStampModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<h1>Year</h1>
#Html.EditorFor(model => model.Year, new { htmlAttributes = new { #class = "form-control" } })
<br />
<br />
<h1>Week No</h1>
#Html.EditorFor(model => model.WeekNo, new { htmlAttributes = new { #class = "form-control" } })
<br />
<br />
<input type="submit" value="Välj" class="btn btn-default">
<br />
<br />
<div>
#Html.ActionLink("Tillbaka", "Index")
</div>
}
then in GetWeekStamp controller post action method, pass the entered year and week number to Stampings view
[HttpPost]
public ActionResult GetWeekStamp(GetWeekStampModel model)
{
return RedirectToAction("Stampings", new { year = model.Year, weekNo = model.WeekNo });
}
The Timestamp property in StampingModel class should be removed and two new properties Year and WeekNo should be added
using System;
using System.Collections.Generic;
using Aviato.Models;
namespace Aviato.ViewModel
{
public class StampingModel
{
public List<Stamping> Stampings { get; set; }
public int Year { get; set; }
public int WeekNo { get; set; }
}
}
in Stampings controller get action method you can calculate the first date of the week based on year and weekNo using your FirstDateOfWeek method above, then use the results as the startTime and set endTime to six days after startTime
public ActionResult Stampings(int year, int weekNo)
{
var startTime = DateConverter.FirstDateOfWeek(year, weekNo);
var endTime = startTime.AddDays(6);
var userId = (int)Session["userId"];
var stampings = _db.Stampings.Where(s => s.Timestamp >= startTime && s.Timestamp <= endTime)
.Where(s => s.UserId == userId).ToList();
var stampingModel = new StampingModel();
stampingModel.Stampings = stampings;
stampingModel.Year = year;
stampingModel.WeekNo = weekNo;
return View(stampingModel);
}
Finally change this part in Stampings view
<p>Du har valt: #Model.Timestamp.Year-#Model.Timestamp.Month-#Model.Timestamp.Day</p>
to this
<p>Du har valt: #Model.Year-#Model.WeekNo</p>

View not working, Passing object to view error

I am working on a project utilizing MVC4 and EF Data First in VS2013. I am getting this error when trying to pass my object to the view.
The model item passed into the dictionary is of type 'System.Data.Entity.Infrastructure.DbQuery1[<>f__AnonymousType34[System.String,System.Nullable1[System.Int32],System.Nullable1[System.Int32],System.Nullable1[System.Int32]]]', but this dictionary requires a model item of type 'System.Collections.Generic.IEnumerable1[TitansMVCWithBootStrap.Models.Player_Game_Stats]'
I am not sure how to fix this, any suggest would help. Thanks
Controller
public class PlayerGameStatsController : Controller
{
private Context db = new Context();
// GET: PlayerGameStats/Details/5
public ActionResult Details(int gid=19, int sid = 11)
{
var playerGameStats = from pgs in db.PlayerGameStats
join p in db.Players on pgs.Player_id equals p.id_player
where pgs.SeasonId == 11 && pgs.GameNumber == 19
select new
{
p.PlayerName,
pgs.PlateAppearance,
pgs.Runs,
pgs.Hits
};
return View(playerGameStats);
}
Model
public class Player_Game_Stats
{
[Key]
[Column(Order = 0)]
public int Player_id { get; set; }
[Key]
[Column(Order = 1)]
public int GameNumber { get; set; }
public Nullable<int> PlateAppearance { get; set; }
public Nullable<int> Runs { get; set; }
public Nullable<int> HR { get; set; }
public int Hits{ get; set; }
//[ForeignKey("id_player")]
//public virtual Players Player { get; set; }
}
}
View
#model IEnumerable<TitansMVCWithBootStrap.Models.Player_Game_Stats>
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Details</h2>
<table class="table table-striped">
<tr>
<th>
#Html.DisplayNameFor(model => model.PlayerName)
</th>
<th>
#Html.DisplayNameFor(model => model.PlateAppearance)
</th>
<th>
#Html.DisplayNameFor(model => model.Runs)
</th>
<th>
#Html.DisplayNameFor(model => model.Hits)
</th>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.PlayerName)
</td>
<td>
#Html.DisplayFor(modelItem => item.PlateAppearance)
</td>
<td>
#Html.DisplayFor(modelItem => item.Runs)
</td>
<td>
#Html.DisplayFor(modelItem => item.Hits)
</td>
</tr>
}
</table>
Also tried
var playerGameStats = (from pgs in db.PlayerGameStats
join p in db.Players on pgs.Player_id equals p.id_player
where pgs.SeasonId == 11 && pgs.GameNumber == 19
select new Player_Game_Stats
{
p.PlayerName,
pgs.PlateAppearance,
pgs.Runs,
pgs.Hits
}).ToList();
return View(playerGameStats);
Try this:
public ActionResult Details(int gid=19, int sid = 11)
{
var playerGameStats = from pgs in db.PlayerGameStats
join p in db.Players on pgs.Player_id equals p.id_player
where pgs.SeasonId == 11 && pgs.GameNumber == 19
select new TitansMVCWithBootStrap.Models.Player_Game_Stats
{
PlayerName = p.PlayerName,
PlateAppearance = pgs.PlateAppearance,
Runs = pgs.Runs,
Hits = pgs.Hits
};
return View(playerGameStats);
}

Understanding Enumerables and ViewModels

I am trying to learn ASP.NET MVC (C#), and am currently tackling ViewModels. I understand the purpose of ViewModels, and I can get data through to the screen using them, but am having difficulties with understanding their relationship with - another new element for me - interfaces.
I want to achieve the following View:
You can see I have a simple initial insert form for adding a new staff member, with a dropdown for salutations. Following this, there is a second form for editing where I iterate through available staff members, placing their values into relevant input fields, where the salutation dropdown defaults to their relative salutation.
I have two Domain Models / tables, Prm_Staff and Prm_Salutation, which I am accessing (wrong word, I think) via the ViewModel Staff_VM:
public class Staff_VM
{
public int StaffID { get; set; }
public int SalutationID { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public bool Active { get; set; }
public List<Prm_Salutation> AvailableSalutations { get; set; }
}
public class StaffMembers
{
public Staff_VM StaffVm;
public IEnumerable<Staff_VM> ListStaffVms;
}
In my controller:
var activeSalts = (from a in db.Prm_Salutations
where a.Active == true
orderby a.Desc ascending
select a).ToList();
var model = new StaffMembers
{
ListStaffVms = (from a in db.Prm_Staffs
where a.Active == true
orderby a.LName ascending
select new Staff_VM
{
StaffID = a.Prm_StaffID,
SalutationID = a.SalutationID,
FName = a.FName,
LName = a.LName,
Active = a.Active,
AvailableSalutations = activeSalts
}),
StaffVm = new Staff_VM()
{
AvailableSalutations = activeSalts
},
};
return View("StaffMembers", model);
In the View, I refer to that model #model November.ViewModels.StaffMembers:
#*Record New Staff Member*#
<tr>
<td>
#Html.DropDownListFor(
model => model.StaffVm.SalutationID,
Model.StaffVm.AvailableSalutations.Select(option => new SelectListItem
{
Text = option.Desc.ToString(),
Value = option.Prm_SalutationID.ToString()
}
),
"Choose...")
</td>
<td>#Html.EditorFor(model => model.StaffVm.FName)</td>
<td>#Html.EditorFor(model => model.StaffVm.LName)</td>
<td>#Html.EditorFor(model => model.StaffVm.Active)</td>
</tr>
#*Update Existing Staff Members*#
#foreach (var staff in Model.ListStaffVms)
{
<tr>
<td>#Html.HiddenFor(model => staff.StaffID)#Html.ValueFor(model => staff.StaffID) </td>
<td>
#Html.DropDownListFor(
model => staff.SalutationID, staff.AvailableSalutations.Select(option => new SelectListItem
{
Selected = (option.Prm_SalutationID == staff.SalutationID),
Text = option.Desc.ToString(),
Value = option.Prm_SalutationID.ToString()
}
),
"Choose...")
</td>
<td>#Html.EditorFor(model => staff.FName)</td>
<td>#Html.EditorFor(model => staff.LName)</td>
<td>#Html.EditorFor(model => staff.Active)</td>
<td>Delete</td>
</tr>
}
ActionResult:
public ActionResult UpdateStaff(StaffMembers list)
{
if (ModelState.IsValid)
{
foreach (var staffVm in list.ListStaffVms)
{
Prm_Staff staff = db.Prm_Staffs.Find(staffVm.StaffID);
staff.SalutationID = staffVm.SalutationID;
staff.FName = staffVm.FName;
staff.LName = staffVm.LName;
staff.Active = staffVm.Active;
}
db.SaveChanges();
ViewBag.rtrn = "Successfully Updated.";
return RedirectToAction("Parameters", new { param = "Staff Members", rtrn = ViewBag.rtrn });
}
else
{
ViewBag.rtrn = "Failed ! Please try again.";
return RedirectToAction("Parameters", new { param = "Staff Members", rtrn = ViewBag.rtrn });
}
}
EDIT: Updated to show most recent changes
I think you should consider change your ViewModel. Also do something like below:
ViewModel
public class Staff_VM
{
public int ID { get; set; }
public int SalutationID { get; set; }
public string FName { get; set; }
public string LName { get; set; }
public bool Active { get; set; }
}
public class MyViewModel
{
public Staff_VM StaffVm { get; set; }
public List<Staff_VM> ListStaffVms { get; set; }
public List<Prm_Salutation> AvailableSalutations { get; set; }
}
Add_Update_Staff Action
[HttpGet]
public ActionResult Add_Update_Staff()
{
var model = new MyViewModel
{
ListStaffVms = (from a in db.Prm_Staffs
where a.Active == true
orderby a.LName ascending
select new Staff_VM
{
ID = a.Id,
SalutationID = a.SalutationID,
FName = a.FName,
LName = a.LName,
Active = a.Active
}),
AvailableSalutations = (from p in db.Prm_Salutations
where a.Active == true
orderby p.Desc ascending
select p).ToList()
};
return View(model);
}
Update Staff Post
[HttpPost]
public ActionResult Add_Update_Staff(MyViewModel model, string buttonType)
{
if (buttonType == "Insert")
{
if (ModelState.IsValid)
{
//save a new staff info
return RedirectToAction("Index", "Home");
}
}
if (buttonType == "Update")
{
foreach (var staffVm in model.ListStaffVms)
{
// update each record here
}
return RedirectToAction("Index", "Home");
}
model.AvailableSalutations = (from p in db.Prm_Salutations
orderby p.Desc ascending
select p).ToList();
return View(model);
}
View
You may need to add validation for insert and update staff info
#using (Html.BeginForm("Add_Update_Staff", "Staff"))
{
<tr>
<td>
#Html.DropDownListFor(
model => model.StaffVm.SalutationID, Model.AvailableSalutations.Select(option => new SelectListItem
{
Text = option.Desc.ToString(),
Value = option.Prm_SalutationID.ToString()
}
), "Choose...")
</td>
<td>#Html.EditorFor(model => model.StaffVm.FName)</td>
<td>#Html.EditorFor(model => model.StaffVm.LName)</td>
<td>#Html.EditorFor(model => model.StaffVm.Active)</td>
</tr>
<input type="submit" value="Insert" name="buttonType" />
for (int i = 0; i < Model.ListStaffVms.Count(); i++)
{
<tr>
<td>#Html.HiddenFor(m => m.ListStaffVms[i].ID)#Html.ValueFor(m => m.ListStaffVms[i].ID) </td>
<td>
#Html.DropDownListFor(
m => m.ListStaffVms[i].SalutationID, Model.AvailableSalutations.Select(option => new SelectListItem
{
Selected = (option.Prm_SalutationID == Model.ListStaffVms[i].SalutationID),
Text = option.Desc.ToString(),
Value = option.Prm_SalutationID.ToString()
}), "Choose...")
</td>
<td>#Html.EditorFor(model => model.ListStaffVms[i].FName)</td>
<td>#Html.EditorFor(model => model.ListStaffVms[i].LName)</td>
<td>#Html.EditorFor(model => model.ListStaffVms[i].Active)</td>
<td>Delete</td>
<hr />
</tr>
}
<input type="submit" value="Update" name="buttonType" />
}

Categories

Resources