SolrNet OR query - c#

I am trying to query records where ParentId = thread OR DataId = Thread. The query keeps timing out on me. Is there something wrong with the query below?
var Test = solr.Query(new SolrQueryByField("ParentId", Thread) ||
(new SolrQueryByField("DataId", Thread)));

I am not an expert in Solr.Net but I have used it for one project. I can only suggest you try couple of things.
First go to your SOLR Admin and try executing the query:
(ParentId:"Thread") OR (DataId:"Thread")
If you get any result back and its not timing out, you can use the same string in Solr.Net like:
string strQuery = "(ParentId:\"Thread\") OR (DataId:\"Thread\")";
// or use * for contains instead of double quotes
var query = new SolrQuery(strQuery);
SortOrder sortOrder = new SortOrder("ParentId");
var solrQueryResult = solr.Query(query, new QueryOptions
{
Rows = 100, //Max Rows returned
Start = 0,
OrderBy = new[] { sortOrder }, //If you want the ordered result
});
var list = solrQueryResult.ToList();//if you want list

You can do this without concatenating strings manually:
ISolrOperations<User> solr = ServiceLocator.Current.GetInstance<ISolrOperations<User>>();
var users = solr.Query(new SolrQuery("age:20") || new SolrQuery("age:30"), options);
More info here:
https://github.com/mausch/SolrNet/blob/master/Documentation/Querying.md

Related

How can get values using LINQ from multilevel variable

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.

LINQ to Entities split string on result

I have a LINQ statement as follows:
var playedBanDataList =
from bannedPlayers in query
select new PlayerBanData
{
Admin = bannedPlayers.Admin,
BannedUntil = bannedPlayers.BannedUntil,
IsPermanentBan = bannedPlayers.IsPermanentBan,
PlayerName = bannedPlayers.PlayerName,
Reason = bannedPlayers.Reason,
IpAddresses = bannedPlayers.IpAddresses.Split(new [] {","}, StringSplitOptions.RemoveEmptyEntries).ToList()
};
return playedBanDataList.ToList();
This fails because split function fails on IpAddresses as LINQ to Entities cannot translate this query to SQL.
This makes sense, but then what's an equivalent way of accomplishing this elegantly? The only way I've thought of is to manually run a loop on the retrieved string then splitting it, but I'd like to get it in one go.
You can use AsEnumerable to make the select occur in memory instead of EF.
var playedBanDataList = query.AsEnumerable()
.Select(bannedPlayers => new PlayerBanData
{
Admin = bannedPlayers.Admin,
BannedUntil = bannedPlayers.BannedUntil,
IsPermanentBan = bannedPlayers.IsPermanentBan,
PlayerName = bannedPlayers.PlayerName,
Reason = bannedPlayers.Reason,
IpAddresses = bannedPlayers.IpAddresses.Split(
new [] {","},
StringSplitOptions.RemoveEmptyEntries).ToList()
});

C# Pulling the Count of tables Associated with ID

Hello I have two tables that look like the following:
PeriodValue
Id (PK)
Name
Description
StartDate
EndDate
ActiveFlg
AcademicTerm
Id (PK)
Year Id (FK)
Name
Start Date
End Date
The objective is to pull the count of terms associated with every period value. This is my code to do so.
public async Task<PeriodValueDTO> GetSchoolYearPeriodValueDTOById (int periodValueId)
{
var value = await Db.PeriodValues.FindAsync(periodValueId);
return new PeriodValueDTO()
{
id = periodValueId,
Name = value.Name,
StartDate = value.Date.ToShortDateString(),
EndDate = value.EndDate.ToShortDateString(),
Description = value.Description
};
}
This method calls the one above
public async Task<List<PeriodValueDTO>> GettAllPeriodValueDTOsByType(int periodTypeId)
{
var toReturn = new List<PeriodValueDTO>();
var pvs = await Db.PeriodValues.Where(x => x.PeriodTypeId == periodTypeId).ToListAsync();
var pvIds = pvs.Select(x => x.Id).ToList();
var periodPeriodVal = await Db.Period_PeriodValue.Where(x => pvIds.Contains(x.PeriodValueId)).ToListAsync();
foreach (var ppv in periodPeriodVal)
{
var periodValue = pvs.FirstOrDefault(x => x.Id == ppv.PeriodValueId);
var value = await GetSchoolYearPeriodValueDTOById(periodTypeId);
var rightId = value.id; //Added this
var terms = Db.AcademicTerms.Where(x => x.YearId == rightId).ToArray(); //Changed This
var dto = new PeriodValueDTO()
{
id = periodValue.Id,
Name = periodValue.Name,
StartDate = periodValue.Date.ToShortDateString(),
EndDate = periodValue.EndDate.ToShortDateString(),
Description = periodValue.Description,
Count = terms.Length //Changed this
};
toReturn.Add(dto);
};
return toReturn;
}
However I am getting this error:
Failed to load resource: the server responded with a status of 500 (Internal Server Error)
Error: Resolving failed with a reason [object Object], but no resolveFailed provided for segment SchoolYear
If I comment out the lines that include var terms, var value, and Count it runs. When they are included I get the error above.
Still a novice to this. Any help would be great.
It's likely because of this line:
var terms = Db.AcademicTerms.Where(x => x.YearId == value.id);
Here, you are trying to generate an expression to be translated into SQL and executed on the database (because Db.AcademicTerms is IQueryable). You are not executing this query in memory. The query parser tries to convert value to a SQL parameter and fails because it is not a primitive object. So you have two choices:
Save value.id into a separate variable and then use that in your query, or better:
Save all AcademicTerms into memory before your loop (I assume there are not hundreds of them) by calling .ToArray() and then query against this. This also resolves the additional N+1 Selects antipattern you have, while allowing greater flexibility.
var value = await GetSchoolYearPeriodValueDTOById(periodTypeId);
should be :
var value = await GetSchoolYearPeriodValueDTOById(periodValue.Id);
no ?

LINQ query with a where condition containing

I am just learning LINQ and I have come across and issue Im not sure how to do in LINQ.
string numbers = "1,3,4,5";
string[] outletsInaStringArray = outlets.Split(',');
List<string> numbersAsAList = outletsInaStringArray.ToList();
I have a field in my database which holds a number. I only want to select the lines WHERE the number in the database is IN the line list of numbers "1,3,4,5" (these numbers are just examples).
Thanks in advance
I have looked at Tim and James answers and also looked at the line that James has sent. Im still a bit confused.....Sorry. Below is my actual code. It compiles but does not work
string outlets = "1,3,4,5"
string[] outletsNeeded = outlets.Split(',');
List<string> outletsNeededList = outletsNeeded.ToList();
DashboardEntities1 db = new DashboardEntities1();
var deptSalesQuery = (
from d in db.DashboardFigures
where (d.TypeOfinformation == "DEPTSALES") && (outletsNeeded.ToString().Contains(d.OutletNo.ToString()))
select new DeptSales
{
Dn = (int)d.Number,
Dnm = "Mens",
On = d.OutletNo,
Qs = (double)d.Value_4,
Se = (double)d.Value_2,
Si = (double)d.Value_3
}
);
In the DASHBAORDFIGURES table in SQL I have 2 records where the outlets number = 1, and therefore should have come up with two records.
Sorry if this is a simple thing, its just new to me and its frustrating.
You can use Contains as tagged:
var query = db.Table
.Where(x => outletsInaStringArray.Contains(x.Number) && x.information == "SALES");
that was method syntax, if you prefer query syntax:
var query = from figure in db.Figures
where outletsInaStringArray.Contains(figure.number)
&& figure.information == "SALES"
select figure;
But the column number is int, the List<string> stores strings, maybe your LINQ provider does not support .Contains(figure.ToString()). Then convert the strings to int first:
List<int> outletsNeededList = outletsNeeded.Select(int.Parse).ToList();
The answer that Tim provided is one method. Linq and lambda are interchangeable. Have a look at the following posting as well. Link
var result = from x in db.Table.ToList()
where outletsInaStringArray.Contains(x.Number)
select x;
Also have a look the following as it offers a very similar solution to the one you are looking for:
Link
As per i understand, you want to fetch data in similar way as IN (SQL) clause does it.
SELECT <Field_List>
FROM Table
WHERE IntegerField IN (1,2,4,5)
But i'm wondering why do you want to do it that way, when you can join data and get only matches. The worse is that you're trying to mix different data type and pass comma delimited text as a set of integers (i may be wrong):
SELECT <Field_List>
FROM Table
WHERE IntegerField IN ("1,2,4,5")
Above query won't execute, because the set of integers is "packed" into comma delimited string. To be able to execute that query, a conversion between data types must be done. Numbers in a string have to be converted to a set of integers (using user define split function or Common Table Expression):
;WITH CTE AS
(
--here convertion occurs
)
SELECT t2.<Field_List>
FROM CTE As t1 INNER JOIN TableName AS t2 ON t1.MyNumber = t2.IntegerField
Linq + any programming language is more flexible. You can build a list of integers (List) to build query.
See simple example:
void Main()
{
List<MyData> data = new List<MyData>{
new MyData(1,10),
new MyData(2, 11),
new MyData(5, 12),
new MyData(8, 13),
new MyData(12, 14)
};
//you're using comma delimited string
//string searchedNumbers = "1,3,4,5";
//var qry = from n in data
// join s in searchedNumbers.Split(',').Select(x=>int.Parse(x)) on n.ID equals s
// select n;
//qry.Dump();
List<int> searchedNumbers = new List<int>{1,2,4,5};
var qry = from n in data
join s in searchedNumbers on n.ID equals s
select n;
qry.Dump();
}
// Define other methods and classes here
class MyData
{
private int id = 0;
private int weight = 0;
public MyData(int _id, int _weight)
{
id = _id;
weight = _weight;
}
public int ID
{
get{return id;}
set {id = value;}
}
public int Weight
{
get{return weight;}
set {weight = value;}
}
}
Result:
ID Weight
1 10
5 12
Cheers
Maciej
Thank you all iv now got it to work using all your suggestions
the final code that works is as follows
DeptSales myDeptSales = new DeptSales(); // Single department
List<DeptSales> myDeptSalesList = new List<DeptSales>(); // List of Departments
DashboardEntities1 db = new DashboardEntities1();
var deptSalesQuery = from d in db.DashboardFigures
join s in outlets.Split(',').Select(x => int.Parse(x)) on d.OutletNo equals s
where (d.TypeOfinformation == "DEPTSALES")
select new DeptSales
{
Dn = (int)d.Number,
Dnm = "Mens",
On = d.OutletNo,
Qs = (double)d.Value_4,
Se = (double)d.Value_2,
Si = (double)d.Value_3
};
Thanks once again.

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();

Categories

Resources