I'm trying to fetch a name from one iList into another where they both contain the same ID.
public class Notifications
{
[JsonProperty("note_id")]
public int note_id { get; set;}
[JsonProperty("sender_id")]
public int sender_id { get; set;}
public string sender_name { get; set; }
[JsonProperty("receiver_id")]
public int receiver_id { get; set; }
[JsonProperty("document_id")]
public int document_id { get; set; }
[JsonProperty("search_name")]
public string search_name { get; set; }
[JsonProperty("unread")]
public int unread { get; set; }
}
public class CompanyDirectory
{
[JsonProperty("contact_id")]
public int contact_id { get; set; }
[JsonProperty("first_name")]
public string first_name { get; set; }
[JsonProperty("second_name")]
public string second_name { get; set; }
[JsonProperty("extension")]
public string extension { get; set; }
[JsonProperty("direct_dial")]
public string direct_dial { get; set; }
[JsonProperty("job_title")]
public string job_title { get; set; }
[JsonProperty("company_id")]
public int company_id { get; set; }
}
Then i'm doing the following, the lists both get populated fine. The weird bit is i'm getting errors saying that where I do CompanyDir.first_name that the property doesn't exist, where it clearly does?:
// This occurs just after the class declaration
public IList<Notifications> Notes;
public IList<CompanyDirectory> CompanyDir;
// Ignore that these both use the same string they're created at different parts of the load process
CompanyDir = JsonConvert.DeserializeObject<IList<CompanyDirectory>>(responseString);
Notes = JsonConvert.DeserializeObject<IList<Notifications>>(responseString);
// Now I thought I should be able to do
foreach(var s in Notes){
var thename = CompanyDir.first_name.Where(contact_id.Contains(s.sender_id))
}
You should look up LinQ and Lambda expressions:
var firstNames = CompanyDir.Where(c => c.contact_id == s.sender_id)
.Select(c => c.first_name)
.ToList();
Now you have a list of firstnames. A list, because there may be zero or more hits for your Where constraint.
Related
I'm building a feature with a jquery datatable, the idea is to have a list of stores in the parent row, and then when expanding the parent to list all the licensed terminals in child rows that are linked to the store parent row by a StoreLicenseId column. The issue I am having is that I have a ViewModel with two models, one for the list of stores and one for the licensed terminals. I'm busy building the method into my controller, my problem is in the second part of the method where I new up "StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()", all the references to tl.terminalId and tl.Terminalname. I get this error "StoreListViewModel does not contain a definition for TerminalID and no accessible extension method". I can see why this is happening, so my question really is, how do I include this "second" TerminalListViewModel into my method to form part of the query ?
ViewModel
public partial class StoreListViewModel
{
public List<TerminalListViewModel> StoreLicenseDetails { get; set; } = null!;
public int Id { get; set; }
public Guid StoreLicenseId { get; set; }
[DisplayName("Store Name")]
public string StoreName { get; set; } = null!;
[DisplayName("App One Licenses")]
public int QtyAppOneLicenses { get; set; }
[DisplayName("App Two Licenses")]
public int QtyAppTwoLicenses { get; set; }
[DisplayName("Date Licensed")]
public DateTime DateLicensed { get; set; }
[DisplayName("Licensed Days")]
public int LicenseDays { get; set; }
[DisplayName("Is License Active")]
public bool LicenseIsActive { get; set; }
}
public partial class TerminalListViewModel
{
public int Id { get; set; }
public Guid StoreLicenseId { get; set; }
public Guid TerminalId { get; set; }
public string TerminalName { get; set; } = null!;
public string LicenseType { get; set; } = null!;
public int TerminalLicenseDays { get; set; }
public DateTime DateLicensed { get; set; }
public bool LicenseIsActive { get; set; }
public bool IsDecommissioned { get; set; }
public DateTime LastLicenseCheck { get; set; }
}
Controller Method
//sl = StoreList
//tl = TerminalList
public IEnumerable<StoreListViewModel> GetStoreList()
{
return GetStoreList().GroupBy(sl => new { sl.StoreLicenseId, sl.StoreName, sl.QtyAppOneLicenses,
sl.QtyAppTwoLicenses, sl.DateLicensed, sl.LicenseDays,
sl.LicenseIsActive })
.Select(sl => new StoreListViewModel()
{
StoreName = sl.Key.StoreName,
QtyAppOneLicenses = sl.Key.QtyAppOneLicenses,
QtyAppTwoLicenses = sl.Key.QtyAppTwoLicenses,
DateLicensed = sl.Key.DateLicensed,
LicenseDays = sl.Key.LicenseDays,
LicenseIsActive = sl.Key.LicenseIsActive,
StoreLicenseId = sl.FirstOrDefault().StoreLicenseId,
StoreLicenseDetails = sl.Select(tl => new TerminalListViewModel()
{
StoreLicenseId = tl.StoreLicenseId,
TerminalId = tl.TerminalId,
TerminalName = tl.TerminalName,
}).ToList()
}).ToList();
}
Based on the error,I suppose your GetStoreList() method returns List<OrderListViewModel> ,but your OrderListViewModel doesn't contains properties of TerminalListViewModel,So you got the error
GetStoreList() method should return List<SourceModel>( Source is the model which contains all the properties of StoreListViewModel and TerminalListViewModel)
For example,the link your provided:Multiple child rows in datatable, data from sql server in asp.net core
public class OrderList
{
//source of properties of OrderListViewModel(parent rows)
public int OrderId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
//source of properties of OrderListDetailViewModel(child rows)
public int KimlikId { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
public class OrderListViewModel
{
public int OrderId { get; set; }
public string Customer { get; set; }
public string OrderDate { get; set; }
public List<OrderListDetailViewModel> OrderListDetails { get; set; }
}
public class OrderListDetailViewModel
{
public int KimlikId { get; set; }
public string Product { get; set; }
public string Color { get; set; }
public int Qntty { get; set; }
}
Orderlist contains all columns OrderListViewModel and OrderListDetailViewModel needs.
When it comes to your case,you should
create 3 models (source,parentrow,childrows)
model for parentrows contains the properties
StoreLicenseId,StoreName, QtyAppOneLicenses,QtyAppTwoLicenses, DateLicensed, LicenseDays,LicenseIsActive
and model for childrows contains the other properties of source model
If you still have questions,please show the data you pulled form db,and I'll write a demo for you
I'm trying to filter a list by the elements from another list, using the following code:
public JsonResult GetEquipamentosByFiliaisInstalacao(List<EmpresaFocusDTO> filiais)
{
var instalacoesFiltradasPorFiliais = _db.Instalacao
.Where(i => filiais.Any(s => s.Id == i.IdFilialFocus))
.ToList()
I'm getting the following error on the linq line:
Unable to create a constant value of type 'MasterCoin.DTO.Focus.EmpresaFocusDTO'. Only primitive types or enumeration types are supported in this context.
What do I have to do?
Here is the classes asked by #er-shoaib :
public class EmpresaFocusDTO
{
public int Id { get; set; }
public string Sigla { get; set; }
}
public partial class Instalacao
{
public int Id { get; set; }
public string Serie { get; set; }
public int Distancia { get; set; }
public int Deslocamento { get; set; }
public int IdEquipamentoFocus { get; set; }
public int IdClienteFocus { get; set; }
public bool Ativo { get; set; }
public string NomeEquipamentoFocus { get; set; }
public string NomeClienteFocus { get; set; }
public int IdFilialFocus { get; set; }
public int IdGrupoFocus { get; set; }
public string NomeFilialFocus { get; set; }
public string NomeGrupoFocus { get; set; }
public int IdRepresentanteFocus { get; set; }
public string NomeRepresentanteFocus { get; set; }
public string Uf { get; set; }
}
As the error says:
Only primitive types are allowed
You need to create a collection of just id columns and then use it in your linq query. Ef is not able to cater with your custom type collection.
Try this:
var ids = filiais.Select(s => s.Id).ToList();
var instalacoesFiltradasPorFiliais = _db.Instalacao
.Where(i => ids .Any(s => s == i.IdFilialFocus))
.ToList()
I have a list like this ( already open with the visual studio debugger ) :
As you can see the list is made up of other objects of the same type list , my need is to run through all the children , regardless by the Index and verify that the FID of that object is the same as the one passed by the UI . Once you found matching server that returns the same object .
i can try this for test,
but considering I only top-level items , those with index 0 , does not flow in all:
AttachmentFolders childWithId17 = ApplicationContext.Instance.companyList[0].AttachmentFolders.SelectMany(parent => parent.AttachmentFolder)
.FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");
another picture to better understand
in fact, I get a list with many elements and should scroll it all , even in responsive manner to be able to return the object that corresponds to that AttachmentFolders FID .
class structure:
public class AttachmentFolders
{
public int id { get; set; }
public String FID { get; set; }
public String Name { get; set; }
public String CPID { get; set; }
public String ParentFID { get; set; }
public List<Attachment> Attachments { get; set; }
public List<AttachmentFolders> AttachmentFolder { get; set; }
}
public class Attachment
{
public int id { get; set; }
public String ATID { get; set; }
public String Name { get; set; }
public String CreatorID { get; set; }
public String FID { get; set; }
public String Extension { get; set; }
public String Description { get; set; }
public int Status { get; set; }
public String CPID { get; set; }
public int FileSize { get; set; }
public DateTime CreationDate { get; set; }
public DateTime ModifiedDate { get; set; }
public int AttachmentType { get; set; }
public int ValidityType { get; set; }
public List<Revisions> Revisions { get; set; }
public String AWID { get; set; }
public String WAID { get; set; }
public String WatermarkPositions { get; set; }
public Boolean Serveroffline { get; set; }
public Boolean IsFavourite { get; set; }
public DateTime LastOpenDate { get; set; }
public int Priority { get; set; }
public String CreatorFirstName { get; set; }
public String CreatorLastName { get; set; }
public String ModifiedByFirstName { get; set; }
public String ModifiedByLastName { get; set; }
public String[] Capabilities { get; set; }
}
Thank you all.
You can write something like the SelectDeep extension as in this Marc's answer: Expressing recursion in LINQ
and then use it in your code instead of SelectMany:
AttachmentFolders child = companyList[0].AttachmentFolders
.SelectDeep(parent => parent.AttachmentFolder)
.FirstOrDefault(child => child.FID == "835A09A2-9D60-46CC-A2BE-D4CBC4C81860");
The SelectDeep method looks as follows:
public static class EnumerableExtensions
{
public static IEnumerable<T> SelectDeep<T>(
this IEnumerable<T> source, Func<T, IEnumerable<T>> selector) {
foreach (T item in source) {
yield return item;
foreach (T subItem in SelectDeep(selector(item), selector)) {
yield return subItem;
}
}
}
}
This is a typical recursion case. You could try searching a flattened tree structure, as done in this or this answer.
If you experience slow performance of this solution, I would think about creating a helper Dictionary<string, AttachmentFolders> object, which would hold all (sub)folder references for quick access, e.g.
IEnumerable<AttachmentFolders> Flatten(AttachmentFolders f)
{
var fs = new[] { f };
return f.Children == null? fs : fs.Concat(f.Children.SelectMany(Flatten));
}
Dictionary<string, AttachmentFolders> GenerateCache(AttachmentFolders firstFolder)
{
return Flatten(firstFolder).ToDictionary(f => f.FID, f => f);
}
Then, one-time at start:
Dictionary<string, AttachmentFolders> Cache = GenerateCache(firstFolder);
And each time a request is made:
if(Cache.ContainsKey(fid)) return Cache[fid];
else throw new Exception("Handle not found FID here");
I have the following data structure
public class Prediction
{
public string Description {get;set;}
public string Id { get; set; }
public List<MatchedSubstring> Matched_substrings { get; set; }
public string Place_id { get; set; }
public string Reference { get; set; }
public List<Term> Terms { get; set; }
public List<string> Types { get; set; }
}
public class GooglePlaceAutocompleteResult
{
public List<Prediction> Predictions { get; set; }
public string Status { get; set; }
}
What I would like to do is remove any items in the Predictions list if their Types collection contains the string "sublocality".
How can I do this with LINQ?
Assuming you are writing a method within GooglePlaceAutocompleteResult, you can write:
Predictions = Predictions.Where(p => !p.Types.Any(t => t.Contains("sublocality")).ToList();
Otherwise the code would be the same but would be result.Predictions = result.Predictions...
I have a really weird issue going on that I can't seem to find the answer on google for.
I currently have the following Code First/DB structure:
public class Prospect {
[Key]
public int ProspectId { get; set; }
public int ProspectCompanyId { get; set; }
public int? ImportUserId { get; set; }
public int? ProspectUserId { get; set; }
public int? SalesUserId { get; set; }
public int? CampaignId { get; set; }
[ForeignKey("CampaignId")]
public virtual ICollection<CampaignEvent> CampaignEvents { get; set; }
[ForeignKey("CampaignId")]
public virtual Campaign Campaign { get; set; }
}
public class CampaignEvent
{
[Key]
public int CampaignEventId { get; set; }
public int CampaignId { get; set; }
public int UserId { get; set; }
public string ActionType { get; set; }
public string ActionSubject { get; set; }
public string ActionTemplate { get; set; }
}
The problem is that when I try to return a query like:
var prospects = db.Prospects.Include("CampaignEvents");
The prospects.First().CampaignEvents is empty - when it should be populated with records.
I've even taken the SQL generated by the Entity Framework and executed it with it successfully returning the prospect and campagin events directly in the database.
I'm at a loss of what to do - its very odd, I receive no errors, just an empty collection.
Please let me know if you need any additional details!
try with
var prospects = db.Prospects.Include("CampaignEvents");
var value = prospects.FirstOrDefault(p=>p.CampaignEvents.Any());