How can get values using LINQ from multilevel variable - c#

I want to unable to fetch values using LINQ. I am using below code for fetching data.
SearchParameters sp3 = new SearchParameters()
{
Filter = "name eq 'test'",
Top = 5,
QueryType = QueryType.Full,
Select= new List<string>() { "Query" },
};
if (highlights)
{
sp3.HighlightPreTag = "<b>";
sp3.HighlightPostTag = "</b>";
}
DocumentSearchResult suggestResult = _indexClient1.Documents.Search(term,sp3);
List<string> suggestions = (from p in suggestResult
.Results.Select(s => s.Document)
.Select(y => y.Values.ToString())
select p).ToList();
Hierarchy is Document->Result->Query.
I am getting values till Result level but I want to get data till Query Level.
I am not expert in LINQ.
screenshot
output

I think what you are looking for is something like this:
suggestResult.Results.SelectMany(s => s.Document.Select(d => d.Query)).ToList()
It should give you a list of all Query-Objects over all Document Results.
If you want the Query as string you have to get another property of Query in the inner Select or call ToString() on it.

Related

Linq: let Count result into a specified column

I've got a table Installation which can contains one or many Equipements.
And for functionnal reasons, I've overwritten my table Installation and added a field NbrEquipements.
I want to fill this field with Linq, but I'm stuck...
Due to special reasons, there is no relation between these to tables. So, no Installation.Equipements member into my class. Therefore, no Installation.Equipements.Count...
I'm trying some stuff. Here is my code:
var query = RepoInstallation.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
int?[] etatIds = { 2, 3 };
query = (from i in query
select new Installation
{
NbrEquipements= (from e in RepoEquipement.AsQueryable()
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
});
But with this try, I got this error:
The entity or complex type 'myModel.Installation' cannot be constructed in a LINQ to Entities query
I've tried some other stuff but I'm always turning around...
Another thing that can be useful for me: It would be great to fill a field called Equipements which is a List<Equipement>.
After that, I would be able to Count this list...
Is it possible ?
Tell me if I'm not clear.
Thanks in advance.
Here is the final code:
//In the class:
[Dependency]
public MyEntities MyEntities { get; set; }
//My Methode code:
var query = MyEntities .SasInstallations.AsQueryable();
// Some filter
query = query.Where(i => i.City.RegionId == pRegionId));
var liste = new List<Installation>();
var queryWithListEquipements =
from i in query
select new
{
Ins = i,
EquipementsTemp = (from eq in MyEntities.Equipements.AsQueryable()
where eq.SpecialId == i.SpecialId
&& (etatIds.Contains(eq.SasEquEtat))
select eq
).ToList()
};
var listWithListEquipements = queryWithListEquipements.ToList();
foreach (var anonymousItem in listWithListEquipements)
{
var ins = anonymousItem.Ins;
ins.Equipements = anonymousItem.EquipementsTemp;
ins.NumberEquipements = ins.Equipements.Count();
liste.Add(ins);
}
return liste;
By the way, this is very very fast (even the listing of Equipements). So this is working exactly has I wished. Thanks again for your help everyone!
Use an anonymous type. EF does not like to instantiate entity classes inside a query.
var results = (from i in query
select new
{
NbrEquipements= (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e.SasId
).Count()
})
.ToList();
Notice how I used select new instead of select new Installation.
You can then use the data inside the list (which is now in memory) to create instances of type Installation if you want like this:
var installations = results.Select(x =>
new Installation
{
NbrEquipements = x.NbrEquipements
}).ToList();
Here is how to obtain the list of equipment for each installation entity:
var results = (from i in query
select new
{
Installation = i,
Equipment = (from e in RepoEquipement
where e.InstallationSpecialId == i.SpecialId
&& (etatIds.Contains(e.EquEtat))
select e).ToList()
})
.ToList();
This will return a list of anonymous objects. Each object will contain a property called Installation and another property called Equipment (which is a list). You can easily convert this list (of anonymous objects) to another list of whatever type that you want.

Linq except two IEnumerable queries

I have a two linq query that returns type of IEnumerable. First query returns filtered values and second query return all values I want to except from second query to first query like minus operator in SQL and bind to my listboxs.
my code sample =>
using (ISession session = SessionManager.CurrentSession)
{
IEnumerable<RoleDefinition> roleAssigned = from groupRole in session.Query<GroupRole>()
join roleDef in session.Query<RoleDefinition>() on groupRole.RoleDefinitionId equals
roleDef.RoleDefinitionId
where groupRole.GroupId == SelectedGroupId
orderby roleDef.RoleName
select new RoleDefinition
{
RoleName = roleDef.RoleName
};
IEnumerable<RoleDefinition> roleUnassigned = from grole in session.Query<RoleDefinition>()
orderby grole.RoleName
select new RoleDefinition
{
RoleName = grole.RoleName
};
List<RoleDefinition> lRoleAss = roleAssigned.ToList();
List<RoleDefinition> lRoleUnAss = roleUnassigned.ToList();
lRoleUnAss = lRoleUnAss.Where(x => !lRoleAss.Contains(x)).ToList();
lsbAssigned.DataSource = lRoleAss;
lsbAssigned.TextField = "RoleName";
lsbAssigned.ValueField = "RoleName";
lsbAssigned.DataBind();
lsbUnAssigned.DataSource = lRoleUnAss;
lsbUnAssigned.TextField = "RoleName";
lsbUnAssigned.ValueField = "RoleName";
lsbUnAssigned.DataBind();
}
EDIT => I fixed my code as below and my function works successfully
List<RoleDefiniton> filteredUnassign = lRoleUnAss.Where(def => !lRoleAss.Select(x => x.RoleName).Contains(def.RoleName)).ToList();
Change the following line:
lRoleUnAss = lRoleUnAss.Where(x => !lRoleAss.Contains(x)).ToList();
To
var results = lRoleUnAss.Except(lRoleAss).ToList();
and use results to get the final list.
I declared a new variable because i do not know if you want to keep the initial list intact or not. If you do not mind changing it you may try:
lRoleUnAss = lRoleUnAss.Except(lRoleAss).ToList();

Linq query how to select all columns

I have a linq query which is giving me desired output :
var data = (from c in dtskip.AsEnumerable()
select new[] {
c.Field<string>("Suburb"), c.Field<string>("Postcode"), c.Field<string>("State"),c.Field<string>("ID"), c.Field<string>("SEARCHKEY"), c.Field<string>("RATING"), c.Field<string>("DELIVERY")
});
How can i select all the column instead of giving name like c.field<string>("postcode") .My output is the data only from datatable dtskip :
output:
["DARWIN","0800","NT","2","DARWINNT","A","Delivery Area"]
,["ALAWA","0810","NT","5","ALAWANT","A","Delivery Area"],
["BRINKIN","0810","NT","6","BRINKINNT","A","Delivery Area"],
is there any other way i can get the output in dis way from datatable using linq query .
DataRow contains an ItemArray member which returns all the data in that row as an array, the downside is they are all returned as objects but if all your columns are the same type you can cast the ItemArray in line to the desired type (in this case string)
dtskip.Rows.Cast<DataRow>().Select(r => r.ItemArray.Cast<string>());
This will give you an IEnumerable<IEnumerable<string>> to work with.
have you tried
var data = (From c in dtskip
select c).AsEnumerable(); //Not sure about the AsEnumerable :s
Are you looking for something like this?
var data = dtskip.AsEnumerable().
Select(x => new
{
Suburb = x.Field<string>("Suburb"),
Postcode= x.Field<string>("Postcode"),
State= x.Field<string>("State"),
Id= x.Field<string>("ID"),
Searchkey = x.Field<string>("SEARCHKEY"),
Rating = x.Field<string>("RATING"),
Delivery = x.Field<string>("DELIVERY")
});

Entity Framework - Join to a List

I need to retrieve a list of entities from my database that matches a list of items in a plain list (not EF). Is this possible with Entity Framework 4.1?
Example:
var list = new List<string> { "abc", "def", "ghi" };
var items = from i in context.Items
where list.Contains(i.Name)
select i;
This works great to return rows that match one property, but I actually have a more complex property:
var list = new List<Tuple<string, string>>
{
new Tuple<string,string>("abc", "123"),
new Tuple<string,string>("def", "456")
};
// i need to write a query something like this:
var items = from i in context.Items
where list.Contains(new Tuple<string,string>(i.Name, i.Type))
select i;
I know that is not valid because it will say it needs to be a primitive type, but is there any way to do what I'm trying to accomplish or will I need to resort to a stored procedure?
You have a few options:
1) You could, of course, write a stored procedure to do what you need and call it.
2) You could read the table into memory and then query the in memory list...that way you don't have to use primitives:
var items = from i in context.Items.ToList()
where list.Contains(new Tuple<string, string>(i.Name, i.Type))
select i;
3) You could also convert your query to use primitives to achieve the same goal:
var items = from i in context.Items
join l in list
on new { i.Name, i.Type } equals
new { Name = l.Item1, Type = l.Item2 }
select i;
I would go with the second option as long as the table isn't extremely large. Otherwise, go with the first.
You need to break it down to sub-properties. For example, something like (this might not compile, i'm not able to test at the moment, but it should give you something to work with):
var items = from i in context.Items
where list.Select(x => x.Item1).Contains(i.Name)
&& list.Select(x => x.Item2).Contains(i.Type)
select i;
You have to think about what the resulting SQL would look like, this would be difficult to do directly in SQL.
My suggestion would be you split out one field of the tuples and use this to cut down the results list, get back the query result then filter again to match one of the tuples e.g.
var list = new List<string> { "abc", "def" };
var list2 = new List<Tuple<string, string>>
{
new Tuple<string,string>("abc", "123"),
new Tuple<string,string>("def", "456")
};
var items = (from i in context.Items
where list.Contains(i.Name)
select i)
.AsEnumerable()
.Where(i => list2.Any(j => j.val1 == i.Name && j.val2 == i.Type);

LINQ syntax help: projection and grouping

New to LINQ.. I am curious as to the syntax to do the following SQL query in LINQ
SELECT MAX(TMPS), DAY FROM WEATHERREADINGS
GROUP BY WEATHERREADINGS.DAY
What I have so far:
var minTemps = from ps in ww.WEATHERREADINGS
group ps by ps.DATE.Hour into psByHour
select new
{
HourOfDay = psByHour.Max().DATE.Hour,
MaxTemp = psByHour.Max().TMPS
};
I am getting the following error while doing this:
Exception Details: System.InvalidOperationException: Could not format node 'New' for execution as SQL.
any help greatly appreciated!!
I think the following is what you want. Note that you can get the key from the grouping so there is no need to aggregate there. You need to provide a mechanism to select the item to do the aggregation on for the other.
var maxTemps = from ps in ww.WEATHERREADINGS
group ps by ps.Date.Hour into psByHour
select new
{
HourOfDay = psByHour.Key,
MaxTemp = psByHour.Max( p => p.TMPS )
};
Or the functional approach that i tend to like better:
var result = ww.WEATHERREADINGS
.GroupBy(a => a.Date.Hour)
.Select(a => new
{
Hour = a.Key,
Max = a.Max(b => b.TMPS)
});

Categories

Resources