MongoDB C# LINQ serialization error - linq

I have a class AttributeValue containing two string fields:
string DataType
string Category
My mongo query is as below:
var test19 = _repo.All().Where(p => p.Rule.Any(r => r.Target.AnyOf.Any(an => an.AllOf.Any(av => av.Match != null && policyFilters2.Contains(string.Concat(av.Match.AttributeValue.DataType, av.Match.AttributeValue.Category))))));
where policyFilters2 is List<string>
The above query gives me an error:
"Unable to determine the serialization information for the expression:
String.Concat(av.Match.AttributeValue.DataType,
av.Match.AttributeValue.Category)."
I am not sure what needs to be done to resolve this.
Any help is greatly appreciated.

I don't think MongoDB can do a search on concatenated values like that. Try concatenating the two fields separately in a field and then try the query.

Eventually, I had to search for both the fields using logical AND rather than concatenating

Related

How to return a query from cosmos db order by date string?

I have a cosmos db collection. I need to query all documents and return them in order of creation date. Creation date is a defined field but for historical reason it is in string format as MM/dd/yyyy. For example: 02/09/2019. If I just order by this string, the result is chaos.
I am using linq lambda to write my query in webapi. I have tried to parse the string and try to convert the string. Both returned "method not supported".
Here is my query:
var query = Client.CreateDocumentQuery<MyModel>(CollectionLink)
.Where(f => f.ModelType == typeof(MyModel).Name.ToLower() && f.Language == getMyModelsRequestModel.Language )
.OrderByDescending(f => f.CreationDate)
.AsDocumentQuery();
Appreciate for any advice. Thanks. It will be huge effort to go back and modify the format of the field (which affects many other things). I wish to avoid it if possible.
Chen Wang.Since the order by does not support derived values or sub query(link),so you need to sort the derived values by yourself i think.
You could construct the MM/dd/yyyy to yyyymmdd by UDF in cosmos db.
udf:
function getValue(datetime){
return datetime.substring(6,10)+datetime.substring(0,2)+datetime.substring(3,5);
}
sql:
SELECT udf.getValue(c.time) as time from c
Then you could sort the array by property value of class in c# code.Please follow this case:How to sort an array containing class objects by a property value of a class instance?

LINQ query to find items where multiple substrings are searched on one column

Select * from web_data where Title like "%Lawn%" || Title like "%silk%"......and so on.
Lawn, Silk etc are in List<web_data>. So i'm looking for a way to search those substrings in the Title column(discription property). One of them must be contained, then the row should be returned.
I've tried this
query = query
.Where(x => filter.FabricType.Any(f => x.discription.Contains(x.discription)))
.AsQueryable();
It's not working. That linq to sql code returns an error:
Local sequence cannot be used in LINQ to SQL implementations of query operators except the Contains operator.
any alternatives?
You can use Contains() or You can also use .StartsWith() or .EndsWith().
collListItem.Where(x => x.discription.Contains("Lawn") || x.discription.Contains("silk")).ToList();

Elasticsearch - with or without a "doc."?

I'm facing some strange issue with "doc." keyword on Nest C# Elasticsearch.
I'm using Couchbase, and I have a class where one of its fields is an array of objects
I try to search inside this array for a specific value.
Something like this:
string mailFilesKey = string.Empty;
ISearchResponse<object> result = _mainManager.Client.Search<object>(c => c
.Type("MailFiles")
.Query(q =>
q.Term("SentFile_Id", fileId))
.Size(1));
Now, this thing actually works. But when I do this one, it doesn't work:
q.Term("doc.SentFile_Id", fileId))
Why?
haha ok nice one. I had this thing long time ago when i started to use Nest and elastic. If you have the object then you can use lambda expressions
like f=>f.SentFile_Id.
Now when you use a string to get the name of the field in nest you must know that all fields, index name, types in elastic are stored with lowercase first letter. So you should use this : q.Term("sentFile_Id", fileId))
Should work just fine.

Filter records using Linq on an Enum type

I'm hoping this is a simple solution. I have a field (PressType) in a table (Stocks) that is seed populated by using an Enum. The table stores the data as an integer. However when I want to query some data via Linq it gives me issues. I can filter any other fields in the table using this format however on the Enum populated field it says
the "==" operator cannot be applied to operands of type "Models.PressType" and "string".
Any help you could give would be appreciated, thanks.
var test = db.Stocks.Where(x => x.PressType == myValue);
There is nothing wrong with your Linq. Your problem is that myValue is of type string. You need to convert your string to the enum first.
string myValue = SomeControl.Text;
Models.PressType myValueAsEnum = (Models.PressType)
Enum.Parse(typeof(Models.PressType), myValue);
IQueryable<Stock> test = db.Stocks.Where(x => x.PressType == myValueAsEnum);

LINQ Query to find all tags?

I have an application that manages documents called Notes. Like a blog, Notes can be searched for matches against one or more Tags, which are contained in a Note.Tags collection property. A Tag has Name and ID properties, and matches are made against the ID. A user can specify multiple tags to match against, in which case a Note must contain all Tags specified to match.
I have a very complex LINQ query to perform a Note search, with extension methods and looping. Quite frankly, it has a real code smell to it. I want to rewrite the query with something much simpler. I know that if I made the Tag a simple string, I could use something like this:
var matchingNotes = from n in myNotes
where n.Tags.All(tag => searchTags.Contains(tag))
Can I do something that simple if my model uses a Tag object with an ID? What would the query look like. Could it be written in fluent syntax? what would that look like?
I believe you can find notes that have the relevant tags in a single LINQ expression:
IQueryable<Note> query = ... // top part of query
query = query.Where(note => searchTags.All(st =>
note.Tags.Any(notetag => notetag.Id == st.Id)));
Unfortunately there is no “fluent syntax” equivalent for All and Any, so the best you can do there is
query = from note in query
where searchTags.All(st =>
note.Tags.Any(notetag => notetag.Id == st.Id))
select note;
which is not that much better either.
For starters see my comment; I suspect the query is wrong anyway! I would simplifiy it, by simply enforcing separately that each tag exists:
IQueryable<Note> query = ... // top part of query
foreach(var tagId in searchTagIds) {
var tmpId = tagId; // modified closures...
query = query.Where(note => note.Tags.Any(t => t.Id == tmpId));
}
This should have the net effect of enforcing all the tags specified are present and accounted for.
Timwi's solution works in most dialects of LINQ, but not in Linq to Entities. I did find a single-statement LINQ query that works, courtesy of ReSharper. Basically, I wrote a foreach block to do the search, and ReSharper offered to convert the block to a LINQ statement--I had no idea it could do this.
I let ReSharper perform the conversion, and here is what it gave me:
return searchTags.Aggregate<Tag, IQueryable<Note>>(DataStore.ObjectContext.Notes, (current, tag) => current.Where(n => n.Tags.Any(t => t.Id == tag.Id)).OrderBy(n => n.Title));
I read my Notes collection from a database, using Entity Framework 4. DataStore is the custom class I use to manage my EF4 connection; it holds the EF4 ObjectContext as a property.

Resources