Filter records using Linq on an Enum type - linq

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

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?

MongoDB C# LINQ serialization error

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

Mapping enums while using dapper

I have the following problem. I am using Dapper to connect to a database, the field that is a varchar in the database is an enum in my object. There is no problem for Dapper to map the database object to my DTO if the enum has the same name as the string in the database. Unfortunately, the strings in the database are not very user friendly and I was wondering if there is a way to map them or convert (only enums) to use more user friendly versions. For example, database value for a field:
SomeVeIRdLooking_Value
And I would like it to map to:
public enum MyEnum {
MyFormattedValue
}
You can select string values from database and convert it by hand.
public enum MyEnum
{
None,
Success,
Failure
}
var enums = connection.Query<string>("select 'None' union select 'Success' union select 'Failure'")
.Select(x => Enum.Parse(typeof (MyEnum), x)) //use your own method to parse enum from string
.ToList();
This is nearly 8 years later, but in case this helps someone else, you can correct "bad" database values with the query
SELECT *,
CASE DbColumnName
WHEN 'SomeVeIRdLooking_Value'
THEN 'MyFormattedValue'
WHEN 'SomeOtherWierd_Value'
THEN 'MyOtherFormattedValue'
ELSE DbColumnName
END AS DbColumnNameFix

Linq to Entities query non primitive type

I have this method I wrote as:
private void GetReceivedInvoiceTasks(User user, List<Task> tasks)
{
var taskList = from i in _db.Invoices
join a in user.Areas on i.AreaId equals a.AreaId
where i.Status == InvoiceStatuses.Received
select i;
}
Basically I was trying to get all the Invoices in the database in the user's area that have a status of received. I don't understand LINQ too well right now.
I'm getting the error:
base {System.SystemException} = {"Unable to create a constant value of
type 'Models.Area'. Only primitive types ('such as Int32, String, and
Guid') are supported in this context."}
Can someone please explain to me what I'm doing wrong and how to remedy this? I can't currently understand what the problem is. If I take the join line out it's fine but I really need that line to make sure I only have invoices from the users area/areas (they can belong to more than one area). Have I got something fundamentally wrong with this query?
Entity framework does not support joins with in-memory collections. You will have to re-wire your query to make use of a Contains query with a collection of primitives instead.
Also EF currently does not support enum values so you will have to compare with an integer value (If InvoiceStatuses.Received is not an enum value ignore this part).
Both fixes combined lead to the following query approach which should result in results equivalent to your join:
int statusReceived = (int)InvoiceStatuses.Received;
var areaIds = user.Areas.Select(x=> x.AreaId).ToArray();
var taskList = from i in _db.Invoices
where i.Status == statusReceived && areaIds.Contains(i.AreaId)
select i;

Dynamic Linq - no property or field exists in type 'datarow'

I am using Northwind Customers Table where I fill the dataset and get the datatable.
I am trying to use dynamic linq and want to select columnName dynamically
var qry = MyDataTable.AsEnumerable().AsQueryable().Select("new(Country)");
Right now I have hard coded country but even then I get this error
No property or field 'Country' exists in type 'datarow'
I would like to eventually change this query to take the column name dynamically.
Please help!!! thanks.
The important hint is here (in bold):
No property or field 'Country' exists
in type 'datarow'
The extension method AsEnumerable of the DataTable class returns an IEnumerable<T> where T has the type DataRow. Now the Select method of Dynamic LINQ wants to work with this type DataRow which hasn't a property Country of course.
You could try this instead:
var qry = MyDataTable.AsEnumerable().AsQueryable()
.Select("new(it[\"Country\"] as CountryAlias)");
it now represents a variable of type DataRow and you can use methods of this type and perhaps also the indexer in my example above. (Dynamic LINQ supports accessing array elements by an integer index, but I am not sure though if accessing an indexer with a string key will work.)
I've used Slauma's answer and it worked. In addition i was doing OrderBy with dynamic linq maybe this will help to someone. I'll just drop the code here.
string dynamicLinqText = $"it[\"{sortColumnName}\"] {sortDirection}"; //it["PERSON_NAME"] asc
result = result.AsEnumerable().OrderBy(dynamicLinqText).CopyToDataTable();

Resources