Relatively new to C# and started using Dynamic LINQ to filter a data table adapter using a string. The issue I'm having is that the Where clause only seems to evaluate the first value in the string and none of the others. Here is the code I am using.
string[] ids = new string[] { "12345", "67891", "45878" };
var resultQ = (from pr in table1 select pr).AsQueryable();
var iq = resultQ.Where("#0.Contains(FieldName)", ids);
It works but only for the first value "12345" so the output of iq displays all fields for "12345". I tried using linq.dynamic.core to see if that would help but the still same result (or I haven't used it properly). I know I'm probably missing something minor here but any help would be greatly appreciated.
Also on a separate note: I wanted to convert the end result of iq which is a IQueryable type to EnumerationRowCollection type. Is this possible?
Thanks in advance
Managed to fix both points now. Either set string[] to string for dynamic LINQ to get all values in list as coded below
string ids = "12345,67891,45878";
var resultQ = (from pr in table1 select pr).AsQueryable();
var iq = resultQ.Where("#0.Contains(FieldName)", ids);
or use Syed's suggestion and change the LINQ query and keep the array (thanks again Seyed)
For the conversion of IQueryable type to EnumerationRowCollection I changed EnumerationRowCollection to IEnumerable and this worked for all my LINQ queries
Thanks
Just use this. It will works fine.
string[] ids = new string[] { "12345", "67891", "45878" };
var resultQ = (from pr in table1 select pr).AsQueryable();
var iq = resultQ.Where(w => ids.Contains(w.Id)).ToList();
Related
I am trying to write a parameterized query that has IN clause.
For Ex :
Working code
Input string : "'guid1','guid2','guid3'"
public List<Employee> GetEmployeeIds(string ids){
QueryDefinition query =new QueryDefinition(#"Select * from Employee where Employee.Id in ("+ ids+")");
var result = GetDetails(query,cosmosClient);
return result;
}
Result: It returns the expected result
Non-working code
Input string : "'guid1','guid2','guid3'"
public List<Employee> GetEmployeeIds(string ids){
QueryDefinition query =new QueryDefinition(#"Select * from Employee where Employee.Id in ( #ids )")
.WithParameter("#ids", ids);
var result = GetDetails(query,cosmosClient);
return result;
}
Result: It returns 0
NuGet package used for above code: Microsoft.Azure.Cosmos 3.8.0
Note: I have tried all the options which are mentioned in this link but it does not work with CosmosClient QueryDefinition Object
WHERE IN with Azure DocumentDB (CosmosDB) .Net SDK
Any help on this is highly appreciated.
Thanks in advance.!!
I'm guessing that your ids value is something like "12,42,94,7". As a string parameter #ids, the expression in (#ids) is broadly the same as in ('12,42,94,7'), which won't match any values, if the values are the individual numbers 12, 42, 94 and 7. When you used the simple contatenated version, the meaning was different - i.e. in (12,42,94,7) (note the lack of quotes), which is 4 integer values, not 1 string value.
Basically: when parameterizing this, you would need to either
use multiple parameters, one per value, i.e. ending up with in (#ids0, #ids1, #ids2, #ids3) with 4 parameter values (either by splitting the string in the C# code, or using a different parameter type - perhaps params int[] ids)
use a function like the STRING_SPLIT SQL Server function, if similar exists for CosmosDB - i.e. in (select value from STRING_SPLIT(#ids,','))
This is working for me, where #ids is an array type:
List<long> ids = new List<long>();
ids.Add(712300002201);
ids.Add(712300002234);
string querySql = #"Select * from Employee where ARRAY_CONTAINS(#ids, Employee.Id )";
QueryDefinition definition = new QueryDefinition(query).WithParameter("#ids", ids);
Have you tried looking into the question asked below.
Azure Cosmos DB SQL API QueryDefinition multiple parameters for WHERE IN
I think ids are being treated as a single string therefore the results are not returning.
Alternatively, you could try using Microsoft.Azure.DocumentDB.Core package and make use of Document Client to write LINQ queries like in the code snippet below.
using (var client = new DocumentClient(new Uri(CosmosDbEndpoint), PrimaryKeyCosmosDB)){
List<MyClass> obj= client.CreateDocumentQuery<List<MyClass>>(UriFactory.CreateDocumentCollectionUri(databaseName, collectionName))
.Where(r => ids.Contains(r.id))
.AsEnumerable();}
After a quite complicated rework of code I stumbled over a small part of code which is not giving me the expected result. The following Linq query should query the data contained in the main object by selecting only those containing a particular string.
The main list contains about 5500 entries. after execution of the Linq query, the secondary object contains still these 5500 entries. Am I blind or already mentally deranged? The CompanyName parameter contains a company which effectively exists.
UPDATE: If the data is taken from the cache the list contains all relevant entries, just the query seems to have no effect.
public List<Account> GetAccountsByValue(string CompanyName)
{
string CacheKey = "Accounts";
ObjectCache dataCache = MemoryCache.Default;
if (dataCache.Contains(CacheKey))
{
var ResultCached = (IEnumerable<Account>)dataCache.Get(CacheKey);
var ResultCached2 = from c in ResultCached
where c.Name.Contains(CompanyName)
select new
{
c.Name,
c.Street,
c.City,
c.ID
};
var temp = ResultCached2.ToList();
return temp;
}
else
{
IList<CrmAccount> Accounts = CrmServiceAgent.GetAccounts();
var ResultNoCache = from CrmAccount f in Accounts
orderby f.DisplayName
select new Account(f);
// put the data in the cache
CacheItemPolicy cacheItemPolicy = new CacheItemPolicy();
cacheItemPolicy.AbsoluteExpiration = DateTime.Now.AddHours(4.0);
dataCache.Add(CacheKey, ResultNoCache, cacheItemPolicy);
return ResultNoCache.ToList();
}
}
The List of data which is queried looks like this (in WCF Test Client)
Everything works fine, just only the query part is not having effect which means that again all entries are returned instead of only thos containing the query parameter.
UPDATE:
Actually I get an Null Reference Exception, probably because the Name-Attribute of the first few entries is null....
This is throwing now the error:
var ResultCached3 = ResultCached.Where(c => c.Name.Contains(CompanyName)).ToList();
I have now fixed the whole thing. The data queried from the database now does not contain any null values anymore. The problem was, that mandatory fields where checked only in the frontend and not on database level. so data which usually is mandatory was imported as null values
so now in the List I have only "valid" data and now the linq query works as it should.
Thank you all for your hints ans suggestions!
kind regards
Sandro
var ResultCached2 = (from c in ResultCached
where c.Name.Contains(CompanyName)
select new
{
c.Name,
c.Street,
c.City,
c.ID
}).ToList();
Is there any way to customize it?
This is what Im trying to do:
string customSelect = "c.person_name";
int per = PersonID();
var RetrievItem = (from c in db.person where c.person_id == per select new { customSelect }).FirstOrDefault();
I've tried to debugging it but it just ended up retrieving given string instead of value from database
Any suggestions #_ #?
In addition to Hamlet's comment about an expression based solution, you can have a look at the Dynamic Linq library. It supports lamba expressions defined as strings, which is exactly what you need.
Using the MongoDB C# driver How can I include more than one field in the query (Im using vb.net)
I know how to do (for name1=value1)
Dim qry = Query.EQ("name1","value1")
How can I modify this query so I can make it find all documents where name1=value1 and name2=value2?
( Similar to )
db.collection.find({"name1":"value1","name2":"value2"})
I wanted to search a text in different fields and Full Text Search doesn't work for me even after wasting so much time. so I tried this.
var filter = Builders<Book>.Filter.Or(
Builders<Book>.Filter.Where(p=>p.Title.ToLower().Contains(queryText.ToLower())),
Builders<Book>.Filter.Where(p => p.Publisher.ToLower().Contains(queryText.ToLower())),
Builders<Book>.Filter.Where(p => p.Description.ToLower().Contains(queryText.ToLower()))
);
List<Book> books = Collection.Find(filter).ToList();
You can use:
var arrayFilter = Builders<BsonDocument>.Filter.Eq("student_id", 10000)
& Builders<BsonDocument>.Filter.Eq("scores.type", "quiz");
Reference: https://www.mongodb.com/blog/post/quick-start-csharp-and-mongodb--update-operation
And doesn't always do what you want (as I found was the case when doing a not operation on top of an and). You can also create a new QueryDocument, as shown below. This is exactly the equivalent of what you were looking for.
Query.Not(new QueryDocument {
{ "Results.Instance", instance },
{ "Results.User", user.Email } }))
I am querying lucene index via nhibernate.search using code below:
var fts = NHibernate.Search.Search.CreateFullTextSession(this._session);
var luceneQuery = "Search:name~0.7 AND Moderated:true NOT PlaceType:WrongType";
var places = fts.CreateFullTextQuery<Place>(luceneQuery)
.List<Place>();
The problem is that query returns all types of Places, including WrongType. When I try to run the same query against the same index in Luke everything is ok, Places of type WrongType are not returned.
Search field is concatenation of many fields in Place object. I am using Moderated and PlaceType fields to filter out some records, as I have discovered, that in this way original sorting order (by score) from Lucene query is preserved.
How can I exclude Places by PlaceType from results using NHibernate.Search?
Ok, so I have found solution.
I have indexed all fields using WhiteSpaceAnalyzer. It seems that NHibernate.Search is using StandardAnalyzer by default, regardless from the fact, that I have set global AnalyzerClass to WhiteSpaceAnalyzer. After parsing the query it looked like that:
"+Search:name~0.7 +Moderated:true -PlaceType:wrongtype"
which didn't work, because values in PlaceType field were not lowercased.
Changing the code in the question to something like that:
var fts = NHibernate.Search.Search.CreateFullTextSession(this._session);
var queryParser = new QueryParser("text", new WhitespaceAnalyzer());
var luceneQuery = "Search:name~0.7 AND Moderated:true NOT PlaceType:WrongType";
var query = queryParser.Parse(luceneQuery);
var places = fts.CreateFullTextQuery(query, typeof(Place))
.List<Place>();
solved the situation.