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).
Related
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();
I have below ItemCountAmount.cs class.
public class ItemCountAmount
{
public int Count { get; set; }
public string Amount { get; set; }
}
and I am referencing it in one more class ChartData.cs as below:
public class ChartData
{
public ChartData()
{
Purchase = Stocks = Sales = new ItemCountAmount();
}
public string period { get; set; }
public ItemCountAmount Purchase { get; set; }
public ItemCountAmount Stocks { get; set; }
public ItemCountAmount Sales { get; set; }
}
Now when I try to assign the values for the ChartData properties, it isn't recognizing or available. Compile time exception will occur in VS.
var model = new ChartData
{
period = yearMonth,
Purchase.Count = await purchase.CountAsync(x => x.order_date.Month == mnth && x.order_date.Year == yr),
}
But Purchase.Count or Purchase.Amount isn't identified here where in if I try it as
var model=new ChartData();
model.Purchase.Count = .....;
model.Purchase.Amount = .....;
.......
it works fine, I mean, property Count and Amount is identified. I am still not getting why the first method is not able to identify the properties from ItemCountAmount.cs class which is referenced in ChartData. Any specific reasons for this?
I don't believe the C# object initialiser supports that syntax, however, you can just do this. I am not sure whether this would result in two constructions and assignemnts to Purchase though, you could break point that yourself and see.
var model = new ChartData
{
Purchase = new ItemCountAmount
{
count = await purchase.CountAsync(x => x.order_date.Month == mnth && x.order_date.Year == yr)
}
}
I have some code that is functioning oddly and was wondering if anyone else hase come across this issue.
I have a view model that collects data from a database via a stored procedure and a vb object (no I do not know vb this is legacy)
When I execute the program the data is collected as expected via the controller. When I debug it I can see all of my parameters populating with information. However when it comes to the view it says that the parameters are null. I have included my code
Models:
public class PersonIncomeViewModel
{
public string IncomeTypeDesc { get; set; }
public string IncomeDesc { get; set; }
public string Income { get; set; }
}
public class PersonIncomeListViewModel
{
public int? PersonId { get; set; }
public List<PersonIncomeListItem> Incomes { get; set; }
public PersonIncomeListViewModel()
{
Incomes = new List<PersonIncomeListItem>();
}
}
public class PersonLookupViewModel : Queue.QueueViewModel
{
public int Action { get; set; }
public bool ShowAdvancedFilters { get; set; }
//Person Search Variables
[Display(Name = #"Search")]
public string SpecialSearch { get; set; }
[Display(Name = #"Person Id")]
public int? PersonId { get; set; }
[Display(Name = #"Full Name")]
public string FullName { get; set; }
[Display(Name = #"SSN")]
public string SSN { get; set; }
public string AddressStatus { get; set; }
public string EmploymentStatus { get; set; }
public PersonIncomeViewModel Income { get; set; }
public List<PersonIncomeListItem> Incomes { get; set; }
public PersonLookupViewModel()
{
Income = new PersonIncomeViewModel();
Incomes = new List<PersonIncomeListItem>();
}
}
Controller:
public ActionResult _Income(int id)
{
var vm = new PersonLookupViewModel();
var personManager = new dtPerson_v10_r1.Manager( ref mobjSecurity);
//var person = personManager.GetPersonObject((int)id, vIncludeIncomes: true);
var person = personManager.GetPersonObject(id, vIncludeIncomes: true);
var look = JsonConvert.SerializeObject(person.Incomes);
foreach (dtPerson_v10_r1.Income income in person.Incomes)
{
if (income.IncomeType_ID == 0)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Unknown",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
if (income.IncomeType_ID == 1)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Alimony",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
if (income.IncomeType_ID == 2)
{
var item = new PersonIncomeListItem
{
IncomeTypeDesc = "Child Support",
IncomeDesc = income.IncomeDesc,
Income = mobjFormat.FormatObjectToCurrencyString(income.Income)
};
vm.Incomes.Add(item);
}
}
return PartialView(vm);
}
View:
#using dtDataTools_v10_r1
#using ds_iDMS.Models.Person
#model ds_iDMS.Models.Person.PersonLookupViewModel
#{
var format = new dtDataTools_v10_r1.CustomFormat();
var newInitials = (Model.Income.IncomeTypeDesc.First().ToString() + Model.Income.IncomeDesc.First().ToString() + Model.Income.Income.First().ToString()).ToUpper();
}
using (Html.DSResponsiveRow(numberOfInputs: ExtensionMethods.NumberOfInputs.TwoInputs))
{
using (Html.DSCard(ExtensionMethods.Icon.CustomText, iconInitials: newInitials, color: ExtensionMethods.Colors.PrimaryBlue))
{
<div>#Model.Income.IncomeTypeDesc</div>
<div>#Model.Income.IncomeDesc</div>
<div>#Model.Income.Income</div>
}
}
There are some extensions that we have built but they are irrelevant to the issue
The line that errors out is this one:
var newInitials = (Model.Income.IncomeTypeDesc.First().ToString() + Model.Income.IncomeDesc.First().ToString() + Model.Income.Income.First().ToString()).ToUpper();
Which drives all of the extension methods on the view and as I run the debugger over it all of the parameters read null, however like I said when I run the debugger and check them in the controller they are populated properly.
Sorry about the long post but I wanted to ensure all the detail was there
This is how to pass the Object model to your Partial View
return PartialView("YourViewName", vm);
or using the Views path
return PartialView("~/YourView.cshtml", vm);
EDIT
Try starting your Action Method like this
var vm= new Person();
vm.PersonLookupViewModel = new PersonLookupViewModel();
Problem solved I had issues with some of my vb objects and had the vb person take a look at them and she fixed them.
Thank you for all the help
EDIT
What had to happen is the vb object had to be re-written and my logic was just fine as it was in the beginning. I marked the one response to my question as the answer because had it been in true MVC without vb objects attached to it, that would have worked perfectly
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.