As a novice am trying my hands on MVC3,razor, EF I have Three connected Tables that I want to produce a view from it. In a simpleton's brief the following are about the tables
PJUsers - ID, memUID(this unique Id from membership),FirstName,LastName
PJAwards - user nominates another user for an award, this links with awardtypesID as foreign key ( awardId,bool:awardok)
PJAwartypes - (awardtypeID, awardName)
The query in the controller is like this
var lists =
from tl in db.PJawards
join u in db.PJUsers on tl.nomineeId equals u.ID into tl_u
join i in db.PJUsers on tl.nominatorId equals i.MemUID into tl_i
where tl.awardOk
orderby tl.awardDated ascending
from u in tl_u.DefaultIfEmpty()
from i in tl_i.DefaultIfEmpty()
select new
{
Status = tl.awardOk,
nomineeFname = u.FirstName,
nomineeLname = u.LastName,
award = tl.PJawards.awardName,
Dated = tl.awardDated,
nominatorFname = i.FirstName,
nominatorLname = i.LastName,
nomineeCountry = u.Citizen,
nomineeResidence = u.Residence,
awardtypeId = tl.ID
};
somewhere i read that i have to construct a model class similar to the query in the controller
{
public class AwardUserInfo
{
public AwardUserInfo() { }
public bool Status { get; set; }
public string nomineeFname { get; set; }
public string nomineeLname { get; set; }
public string award { get; set; }
public string Dated { get; set; }
public string nominatorFname { get; set; }
public string nominatorLname { get; set; }
public string nomineeCountry { get; set; }
public string nomineeResidence { get; set; }
public int awardtypeId { get; set; }
}
}
Please I learn by examples so to be able to help me assume I don't know anything
somewhere i read that i have to construct a model class similar to the query in the controller
Try this.
I guess your ef-model is similar to
So You can create a ViewModel class
public class PJAwardsViewModel
{
public int Id { get; set; }
public string NominatorFName { get; set; }
public string NomineeFname { get; set; }
public string AwardName { get; set; }
public bool IsAwarded { get; set; }
}
It will be also good if You add some service class
public class PJAwardsService
{
public static List<PJAwards> GetAll()
{
using (var context = new YourDBEntities())
{
return context.PJAwards
.Include(x => x.PJUsers)
.Include(x => x.PJUsers1)
.Include(x => x.PJAwartypes).ToList();
}
}
}
(Don't forget to write using System.Data.Entity; )
Then You can add a ViewModelHelper class
public class PJAwardsViewModelHelper
{
public static PJAwardsViewModel PopulatePJAwardsViewModel(PJAwards pjaward)
{
return new PJAwardsViewModel
{
Id = pjaward.Id,
NominatorFName = pjaward.PJUsers.FirstName,
NomineeFname = pjaward.PJUsers1.FirstName,
AwardName = pjaward.PJAwartypes.AwardName,
IsAwarded = pjaward.IsAwarded
};
}
public static List<PJAwardsViewModel> PopulatePJAwardsViewModelList(List<PJAwards> pjawardsList)
{
return pjawardsList.Select(x => PopulatePJAwardsViewModel(x)).ToList();
}
}
At the end Your controller index method will look like this
public ActionResult Index()
{
var pjawards = PJAwardsViewModelHelper.PopulatePJAwardsViewModelList(PJAwardsService.GetAll().ToList());
return View(pjawards);
}
The only thing You should do is add a view (build the project before). Choose PJAwardsViewModel as a Model class and List as a scaffold template.
Enjoy it.
Here is a step by step guide by Steven Sanderson on how to use Asp.net MVC3, EF Code First with MVCScaffolding (powershell automation).
http://blog.stevensanderson.com/2011/01/13/scaffold-your-aspnet-mvc-3-project-with-the-mvcscaffolding-package/
It is a multipart blog post takes you through the exciting journey of MVC3.
All the best.
Related
I am currently struggling to accept a list of objects from FormData in ASP.NET Core.
The project looks like this:
I have a class called Stavka (English: Item).
public class Stavka
{
public string naziv { get; set; }
public double cenaPoJedinici { get; set; }
public string jedinicaMere { get; set; }
public int kolicina { get; set; }
public Stavka(string naziv, double cenaPoJedinici, string jedinicaMere, int kolicina)
{
this.naziv = naziv;
this.cenaPoJedinici = cenaPoJedinici;
this.jedinicaMere = jedinicaMere;
this.kolicina = kolicina;
}
public Stavka()
{
}
}
I have a class called Faktura (English: Bill) which has a variable called Stavke (English: Items) that is a list containing the Stavka objects.
public class Faktura
{
public int Id { get; set; }
public string pibStart { get; set; }
public string pibEnd { get; set; }
public DateTime datumGen { get; set; }
public DateTime datumRok { get; set; }
public List<Stavka> stavke { get; set;}
public double cena { get; set; }
public string tip { get; set; }
public Faktura(int id, string pibStart, string pibEnd, DateTime datumGen, DateTime datumRok, List<Stavka> stavke, string tip)
{
Id = id;
this.pibStart = pibStart;
this.pibEnd = pibEnd;
this.datumGen = datumGen;
this.datumRok = datumRok;
this.stavke = stavke;
this.tip = tip;
double sumCena = 0;
foreach(Stavka s in stavke)
{
sumCena += s.kolicina * s.cenaPoJedinici;
}
this.cena = sumCena;
}
public Faktura()
{
}
I want to create a new Faktura object and add it to a list within my Controller. I tried to do this with the following code:
[HttpPost("dodajFakturu")]
public IActionResult dodajFakturu([FromForm]string pibStart, [FromForm]string pibEnd,[FromForm]DateTime datumStart, [FromForm]DateTime datumEnd,[FromForm]List<Stavka> stavkeLis, [FromForm]string tip)
{
int id = lst.OrderByDescending(p => p.Id).First().Id + 1;
Faktura f = new Faktura(id, pibStart,pibEnd, datumStart,datumEnd,stavkeLis,tip);
lst.Add(f);
return Ok(SveFakture());
}
And yet, when i post the request (in Swagger/Postman), the variable stavkeLis (which accepts the JSON array) is always empty:
This is certainly because i fundamentally misunderstood the way in which NET Core accepts these variables.
Is there some other way to send a list of objects through form data?
this way you have is currect, but if its not maybe because simple code problem but way that you right the code can be better or you can say develop your code as Below:
// StavkaBody => I Mean All Body In One Json
public async Task<IActionResult> MethodName([FromForm] string
StavkaBody)
{
YourObjectType object = new YourObjectType();
// this will be Populate All Json To Single object And
// You dont Need To Add some Constructors For Done this
JsonConvert.PopulateObject(StavkaBody, objec);
// Example Usage
Console.WriteLine(object.Name);
}
in Here I`ve Used The Newtonsoft.Json For this And Its Make Your Model So Much Simpler.
I Hope Its Helps
here is my setup.
Base Model
public class Base
{
public int BaseID { get; set; }
[StringLength(8)]
[Index(IsUnique = true)]
public string BaseNumber { get; set; }
public ICollection<BillOfMaterial> billOfMaterials { get; set; }
}
BillOfMaterial Model
public class BillOfMaterial
{
public int BillOfMaterialID { get; set; }
[StringLength(10)]
[Index(IsUnique = true)]
public string BomNumber { get; set; }
public ICollection<Base> Bases { get; set; }
}
What I am trying to do is select all bill of material BomNumbers where the base is equal to a input base number.
What I have tried
BaseNumber = "A1C1D001";
var BOMQuery = (from Base in db.Bases.Include("BillOfMaterials")
where Base.BaseNumber == BaseNumber
select Base.billOfMaterials.ToList());
When trying to create this query I can't see the BomNumber property when I do => select Base.BillOfMaterials.(Can't Find Property)
I tried using the .Include() extension to try and bring in the related table in hopes it would give me the property. Not sure how to word this question exactly to do a good google search for the answer. What am I doing wrong here? Any help would be appreciated.
Thank you,
When you only need a list of BOMs use the following:
var BOMQuery = db.Bases
.Where(x => x.BaseNumber == BaseNumber)
.SelectMany(a => a.billOfMaterials.Select(b => b.BomNumber)).ToList();
You can then add it to an ObservableCollection like this:
BomList = new ObservableCollection<string>(BOMQuery);
I'm really not understanding this as I've only dabbled in MVC and C#. I apologize if my terminology is wrong or confusing, I will do my best to answer questions. I have a couple models like so:
public class DataSharingModels
{
public string ReferenceID { get; set; }
public NBTC NBTCGroup { get; set; }
public Contractors ContractorsGroup { get; set; }
public Coordinators CoordinatorsGroup { get; set; }
public NGO NGOGroup { get; set; }
public Public PublicGroup { get; set; }
public SelectList FA_RA_List { get; set; }
}
public class NBTC
{
public String NBTC_FA_Centroid { get; set; }
public String NBTC_FA_Bound { get; set; }
public String NBTC_RA_Centroid { get; set; }
//more properties...
}
The DataSharingModels class contains the public NBTC NBTCGroup property. It is not public List<NBTC> NBTCGroup because there will only be one produced per instance of the controller being hit.
Now in my controller, I have a LINQ statement that selects a new NBTC class:
var nbtcVals = (from ds in db.SharingPermissions
where ds.FocalRefID.ToString() == ReferenceID
&& ds.ShareGroup == "NBTC"
select new NBTC
{
NBTC_FA_Centroid = ds.CIP_FA_Centroid,
NBTC_FA_Bound = ds.CIP_FA_Boundary,
NBTC_RA_Centroid = ds.CIP_RA_Centroid,
//more properties...
});
Where I'm going wrong is I would like to add that to my DataSharingModels model. I thought the nbtcVals type would be NBTC, but it's IQueryable<##.Models.NBTC>. I understand I could do this, but it seems redundant:
DataSharingModels dsm = new DataSharingModels();
if (nbtcVals.Any())
{
foreach (var i in nbtcVals)
{
dsm.NBTCGroup.NBTC_FA_Centroid = i.NBTC_FA_Centroid;
dsm.NBTCGroup.NBTC_FA_Boundary = i.NBTC_FA_Bound;
dsm.NBTCGroup.NBTC_RA_Centroid = i.NBTC_RA_Centroid;
//more properties...
}
}
What is a more direct way to do this? There must be one. I supposed I could also return an anonymous type in the LINQ query and then assign each property in the foreach like dsm.NBTCGroup.NBTC_RA_Centroid = i.NBTC_RA_Centroid but that seems the same as the other way.
var nbtcgroup = (from ds in db.SharingPermissions
where ds.FocalRefID.ToString() == ReferenceID
&& ds.ShareGroup == "NBTC"
select new NBTC
{
NBTC_FA_Centroid = ds.CIP_FA_Centroid,
NBTC_FA_Bound = ds.CIP_FA_Boundary,
NBTC_RA_Centroid = ds.CIP_RA_Centroid,
//more properties...
})
.OrderByDescending(n => n.Id) // or some other property that could identify sorting
.FirstOrDefault();
This one has a translation to SQL (LIMIT or TOP depending on backend).
I have the following code where I am creating a IList that I need to filter by the data in another list called List. The locations list represents the locations a user is allowed to view based on their permissions. I am new to LINQ and am confused with error I get (C# Unknown method "Where(?)" of "System.Ling.IQueryable". I have tried various syntax arrangement using either Contains() and Any() or both to no avail. I feel like it's something very basic that I don't understand about doing this. Here is the code:
----- users locations
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
namespace Decking.Models
{
public class locations
{
[Key]
public string org_id { get; set; }
}
}
///////// here is the view model
using System.ComponentModel.DataAnnotations;
using System;
namespace Decking.Models
{
public class InventoryViewModel
{
[Key]
public int id { get; set; }
public DateTime metric_dt { get; set; }
public int? item_id { get; set; }
public int? loc_type_id { get; set; }
public string trlr_nbr { get; set; }
public string user_id { get; set; }
public string org_id { get; set; }
public Double numerator { get; set; }
//these are the child entities
[UIHint("ClientItem")]
public ItemViewModel Items
{
get;
set;
}
[UIHint("ClientLocTypes")]
public LocTypesViewModel LocTypes
{
get;
set;
}
[UIHint("ClientOrgsByUser")]
public OrgsByUserViewModel OrgsByUser
{
get;
set;
}
}
}
///////// code to populate the view model
public IList<InventoryViewModel> GetAll(List<locations> locs)
{
IList<InventoryViewModel> result = new List<InventoryViewModel>();
result = entities.inventory.Select(inventory => new
InventoryViewModel
{
id = inventory.id,
metric_dt = inventory.metric_dt,
item_id = inventory.item_id,
loc_type_id = inventory.loc_type_id,
trlr_nbr = inventory.trlr_nbr,
org_id = inventory.org_id,
numerator = inventory.numerator,
user_id = inventory.user_id,
Items = new ItemViewModel()
{
item_id = inventory.items.item_id,
item_desc = inventory.items.item_desc,
},
LocTypes = new LocTypesViewModel()
{
loc_type_id = inventory.loc_types.loc_type_id,
loc_desc = inventory.loc_types.loc_desc,
},
OrgsByUser = new OrgsByUserViewModel()
{
user_id = inventory.user_id,
//mgr_emp_nbr = inventory.mgr,
org_id = inventory.org_id,
},
}).Where(e => e.metric_dt == DateTime.Today && e.org_id
==locs.Any(o=>o.org_id)) // this doesn't work
//}).Where(e => e.metric_dt == DateTime.Today && e.org_id == "SGF") //
this works
.ToList();
return result;
}
Any help you can provide would be greatly appreciated! Thank so much!
The problem is in e.org_id == locs.Any(o=>o.org_id). As I can see in your working example, your org_id is a string.
I guess what you are trying to do is .Where(e => e.metric_dt == DateTime.Today && locs.Any(o=>o.org_id == e.org_id))
I don't know how to convert LINQ query to List type of Owner with data from Transport table and pass it to WPF form (using MVVM)
DB structure :
Owner has many cars, so I described relation like this:
public partial class Transport
{
public Transport()
{
TransportOwners = new List<TransportOwner>();
}
[Key]
public int TransportID { get; set; }
public string PlateNo { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public virtual ICollection<TransportOwner> TransportOwners { get; set; }
}
public partial class Owner
{
[Key]
public int OwnerID { get; set; }
public int TransportID { get; set; }
[ForeignKey("TransportID")]
public virtual Transport Transport { get; set; }
[NotMapped]
public string PlateNo { get; set; }
[NotMapped]
public string Brand { get; set; }
[NotMapped]
public string Model { get; set; }
}
In ViewModel I created list type of Owner :
private List<Owner> _haveList;
public List<Owner> HaveList
{
get { return _haveList; }
set
{
if (value != _haveList)
{
_haveList = value;
RaisePropertiesChanged("HaveList");
}
}
}
Now I am trying to get the data :
using (var dbContext = new DataModelContext())
{
var query = dbContext.Owners.AsQueryable();
query = query.Where(o => o.OwnerId.Equal(OwnerParameter));
query = query.Select(t => new
{
Model = t.Transport.Model,
Brand = t.Transport.Brand,
PlateNo = t.Transport.PlateNo
}).ToList();
// Here I see data I need (list of Transport by Owner)
HaveList = query;
'System.Collections.Generic.List<<anonymous type: ... >>' to 'System.Collections.Generic.List<DataModels.Owner>'
In Linq-to-Entities you can only project to an anonymous type or a regular class. You can't project to an existing entity type
var result = (from o in query
where o.OwnerID==OwnerParameter
select new OwnerModel
{
Model=o.Transport.Model,
Brand=o.Transport.Brand
}).ToList();
1 - You should try to use a named object
HaveList= query.Select(t => new OwnerModel
{
Model = t.Transport.Model,
Brand = t.Transport.Brand,
PlateNo = t.Transport.PlateNo
}).ToList();
2 - Your query object is created as IQuerible, then you try to assign it as a List
query = query should not work I think.
Note that OwnerModel should fire INotificationEvent when one of the property is modified :)
private List<OwnerModel> _haveList;
public List<OwnerModel> HaveList
{
get { return _haveList; }
set
{
if (value != _haveList)
{
_haveList = value;
RaisePropertiesChanged("HaveList");
}
}
}
Finally I have what I need, thank You for Your help
List<Owner> list = DBContext.Owners.Where(to => to.OwnerID == ownerParameter).ToList();
HaveList = list.Select(t => new Owner()
{
Model = t.Transport.Model,
Brand = t.Transport.Brand,
PlateNo = t.Transport.PlateNo
}).ToList();