LINQ Selecting a List within a List - c#

I'm trying to fill a list within a list using LINQ to query my database.
The issue I'm facing is that I'm unsure how to select the data into the child list.
When trying to execute the code below, I receive the error
Error 1 Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)
The model classes are like so:
public class _LayoutViewModel
{
public List<CallGuideMenuL1> CGL1 { get; set; }
}
public class CallGuideMenuL1
{
public string Area { get; set; }
public List<CallGuideMenuL2> Products { get; set; }
}
public class CallGuideMenuL2
{
public int CallGuideProductId { get; set; }
public string Product { get; set; }
}
And the DB context:
public class CallGuideArea
{
public int CallGuideAreaId { get; set; }
public string Area { get; set; }
public List<CallGuideProduct> CallGuideProducts { get; set; }
}
public class CallGuideProduct
{
public int CallGuideProductId { get; set; }
public string Product { get; set; }
public int CallGuideAreaId { get; set; }
public DateTime Added { get; set; }
public DateTime? Deleted { get; set; }
}
In my controller I'm trying to select the data like so:
_LayoutViewModel vm = new _LayoutViewModel();
vm.CGL1 = from a in db.CallGuideArea
.SelectMany(p => p.CallGuideProducts)
select a;
I'm pretty sure it's the select a; line that's the issue as I need to assign the data back to the properties of both CallGuideMenuL1 and CallGuideMenuL2.
Could anyone point me in the right direction around the right LINQ expression?

vm.CGL1 = db.CallGuideArea.Select(a => new CallGuideMenuL1()
{
Area = a.Area,
Products = a.CallGuideProducts.Select(p => new CallGuideMenuL2()
{
CallGuideProductId = p.CallGuideProductId,
Product = p.Product
}).ToList()
}).ToList();

Probably vm.CGL1 is declared as List so you need to select into List:
vm.CGL1 = (from a in db.CallGuideArea
.SelectMany(p => p.CallGuideProducts)
select a).ToList();
or you will need to project:
vm.CGL1 = (from a in db.CallGuideArea
.SelectMany(p => p.CallGuideProducts)
select new CallGuideMenuL1()
{
Area = a.--some property
...
}).ToList();

Related

Dynamic Linq Filtering with Parent Property not working

I have question related to dynamic Linq.
I have a class structure defined as below.
public class UserProfile
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public long Overtime { get; set; }
public UserProfileDetails UserProfileDetails { get; set; }
}
public class UserProfileDetails
{
public UserProfileDetails()
{
LstString = new List<string>();
}
public string Department { get; set; }
public double Salary { get; set; }
public int LeaveBalance { get; set; }
public List<string> LstString { get; set; }
}
Created a object of UserProfile like given below.
var a = new UserProfile();
For a normal Linq I can execute the following. I am trying to find all the strings in UserProfileDetails while is not same a my first name.
var vvv = a.UserProfileDetails.LstString.Where(x => !x.Equals(a.FirstName)).ToList();
I want to convert the above linq to dynamic linq and used the following
var vDyna = a.UserProfileDetails.LstString.AsQueryable().Where("!Equals(FirstName)").ToList();
But the above is giving the error:
System.Linq.Dynamic.Core.Exceptions.ParseException: 'No property or field 'FirstName' exists in type 'String''.
Can anyone help me with this please?
I think it's similar to the LINQ function. In the where string you have to use the UserProfile variable a.
Your Code:
var vDyna = a.UserProfileDetails.LstString.AsQueryable().Where("!Equals(FirstName)").ToList();
My suggestion:
var vDyna = a.UserProfileDetails.LstString.AsQueryable().Where(s => !s.Equals(a.FirstName)).ToList();
I never used Dynamic Linq, but maybe that helps.
Source:
https://learn.microsoft.com/en-us/dotnet/api/system.linq.queryable.where?view=net-5.0
EDIT 1:
var vDyna = a.UserProfileDetails.LstString.AsQueryable().Where("!Equals(#0)", a.FirstName).ToList();

Convert flat to hierarchy list?

I have two tables "CategoryGroup" and "Category" which returns data in one list. Requirement is to convert flat list to hierarchy list like CategoryGroup contains related categories.
Please suggest how to convert into hieararchy list?
public class ProfileConditionGroup
{
public Guid ConditionGroupGUID { get; set; }
public string ConditionGroupName { get; set; }
public List<ProfileConditionList> profileConditions { get; set; }
}
public class ProfileConditionList
{
public string ConditionName { get; set; }
public Nullable<Guid> ConditionGUID { get; set; }
public string[] ThisConditionSelectedByProfileIDs { get; set; }
public Nullable<Guid> ParentConditionGroupGUID { get; set; }
public bool IsDefaultSelected { get; set; }
}
This is actually a little tricky without having an actual concrete return type, but here's the way I'd tackle it if you're just building a tree of Guid values.
Given this query:
var query =
from pcg in pcgs
from pcl in pcg.profileConditions
select new
{
pcg.ConditionGroupName,
pcg.ConditionGroupGUID,
pcl.ConditionName,
pcl.ConditionGUID,
pcl.ThisConditionSelectedByProfileIDs,
pcl.ParentConditionGroupGUID,
pcl.IsDefaultSelected,
};
...I'd do this:
var lookup = query.ToLookup(x => x.ParentConditionGroupGUID);
Func<Guid?, Tree<Guid?>> build = null;
build = g =>
{
var r = new Tree<Guid?>() { Value = g };
r.AddRange(lookup[g].Select(x => build(x.ConditionGroupGUID)));
return r;
};
Now you just call build(null) and you should get a tree of Guid?. If you can create you're own output class you'd change the function to Func<Guid?, Tree<YourOutputClass>>.
You need this class for the tree:
public class Tree<T> : List<Tree<T>>
{
public T Value { get; set; }
}

issue with select clause in linq - to - entities query

Hello I'm using code first approach and I defined the following model:
public partial class tmmodel
{
public tmmodel()
{
this.tmmodel_L10n = new HashSet<tmmodel_L10n>();
}
public int id { get; set; }
public int Order { get; set; }
public bool Active { get; set; }
public virtual ICollection<tmmodel_L10n> tmmodel_L10n { get; set; }
}
public partial class tmmodel_L10n
{
public int modelid { get; set; }
public int CultureId { get; set; }
public string Title { get; set; }
public string Text { get; set; }
public virtual tmmodel tmmodel { get; set; }
}
So I want to get in an anonymous class - the id, Active and order property of my tmodel along with teh title in tmodel_L10:
With Linq i MANAGED TO GET the result - but when I try to use Linq - to - sql - I have some problems :
var items = from i in dc.tmmodel
join l10n in dc.tmmodel_L10n on new { i.id, cid = 1 } equals new { l10n.modelid, cid = l10n.CultureId }
select new
{
id = i.id,
i.Order,
i.Active,
l10n.Title,
};
Here is my - linq to entites query and you can see that I don't have any access to the Title property:
var linqtosqlitems = dc.tmmodel
.Include(x => x.tmmodel_L10n)
.Select(l => new {id = l.id,l.Active,**l.tmmodel_L10n.??**}).ToList();
By using include Linq Creates an Enumarable of your "child" table because it can be one to many relationship. If You are sure there is only one record in "child table" You can go like:
var linqtosqlitems = dc.tmmodel
.Include(x => x.tmmodel_L10n)
.Select(l => new {id = l.id,l.Active,l.tmmodel_L10n.FirstOrDefault().Title}).ToList();

Multiple collections in an object using Linq

I have following object
public class bizObj
{
public string name { get; set; }
public int p_id { get; set; }
public string acc_number { get; set; }
public string a_name { get; set; }
public string a_phone { get; set; }
public virtual product product { get; set; }
public virtual account account { get; set; }
}
Linq statment to get data from db is
public IEnumerable<bizObj> GetbizObj(int id)
{
var acs = (from c in db.p_account
where c.p_id==id
select new bizObj
{
name = c.p_name,
p_id = c.product.id,
acc_number=c.account.acc_number,
a_name = c.a_name,
a_phone = c.a_phone
});
return acs;
}
The above code is working fine but it is returning one collection. What I am trying to
get is that it has a collection of
{
name,
p_id
//than a second collection which has all the records that have same name ane p_id
{
acc_number,
a_name
a_phone
}
}
Please let me know how I can accomplish this using linq/lambda expression. Thanks
Question is unclear, but it looks like you're saying you want to group rows by name and p_id.
var query = acs.GroupBy(x => new { x.name, x.p_id })
.Select(g => new { g.Key.name, g.Key.p_id, Items = g.ToList() });

Linq select nested rows

I have the following class:
public class PingtreeTier
{
public BuyerType BuyerType { get; set; }
public int ID { get; set; }
public int MaxRequests { get; set; }
public IEnumerable<PingtreeNode> Nodes { get; set; }
public int Seq { get; set; }
public int Timeout { get; set; }
public bool Weighted { get; set; }
}
As you can see PingtreeTier contains an IEnumerable<PingtreeNode> class. This PingtreeNode class has a property named Status. Using Linq, I need to select only the Tiers/Nodes where PingtreeNode Status = 'Active'.
Anyone help as I'm struggling with the syntax for this.
How about using .Any or .All here:
var results = tiers.Where(t => t.Nodes.Any(n => n.Status == "Active"));
This will select any PingtreeTiers that contain at least one PingTreeNode with Status equal to "Active".
If you wanted to select only PingtreeTiers whose PingTreeNodes are all active, you could use the .All extension method instead:
var results = tiers.Where(t => t.Nodes.All(n => n.Status == "Active"));

Categories

Resources