I have a field in my database that holds a DateTime?. I would like to sort the results so that the NULLs show up at the top, then descending by DateTime, e.g.,
null
null
2012-04-01
2012-01-01
2011-09-04
The reason is that I am looking at expiration dates, though some entries do not expire.
You can return DateTime.MaxValue instead of null from the ordering expression, so rows with null dates are sorted first:
yourData.OrderByDescending(row => row.dateTimeField ?? DateTime.MaxValue);
I find the most straightforward approach to be:
data.OrderBy(Function(o) o.myDate IsNot Nothing).ThenByDescending(Function(o) o.myDate)
in C# I think...
data.OrderBy(o => o.myDate != null).ThenByDescending(o => o.myDate)
This will also work with LINQ to SQL. I'm not sure if if(nullable, value) will successfully translate to SQL.
You could try something like this:
var nulls = table.Where(x => x.NullableDateTimeField == null);
var notNulls = table.Where(x => x.NullableDateTimeField != null);
var result = nulls.Concat(notNulls.OrderByDescending(x => x.NullableDateTimeField));
It's more "obviously correct" than "likely to be super-efficient", but it's at least a starting point.
Take a look at David Oesterreich's blog:
var queryResult =
orderedProducts from enumerableProducts
order by orderedProducts.ProductName,
orderedProducts.Price != null ? 1 : 0 descending,
orderedProducts.Price
select orderedProducts;
like the accepted version above but with syntax for c# v6
tickets.OrderByDescending(x => x?.Erstellt ?? DateTime.Now)
Related
I want to use OR function in my linq query.
Ex:
Sql:
select * from tblusers where userid=1 and status='a' or status='b';
Linq:
var result= _Repository.selectAll().where(x=>x.UserID==1 && x.status=="a" OR x.status=="B");
It's does work for linq query. so does anyone have any idea?
So you are aware about the && operator for comparison, then why not make a try with || operator? Anyway here is the solution for your problem, Following code will get you the result with UserID is 1 and status is either a or B.
_Repository.selectAll().where(x=>x.UserID==1 && (x.status=="a" || x.status=="B"));
Create an array of status you want to check and then use contains. something like this.
var statusList = new[] {"a", "b"};
.Where(x=> x.UserID == 1 && statusList.Contains(x.status));
Adding my 2 cents in here, there is another way you can write your sql query in C# which more or less resembles the sql syntax.
var result = from x in _Repository.SelectAll() where x.UserID == 1 && (x.Status == "a" || x.Status == "B") select x;
This syntax is Query Syntax/Expression where as your snippet is Method Syntax/Expression. Both will achieve same results. Also behind the scene, query syntax is compiled to Method syntax.
At compile time, query expressions are converted to Standard Query Operator method calls according to the rules set forth in the C# specification. Any query that can be expressed by using query syntax can also be expressed by using method syntax. However, in most cases query syntax is more readable and concise.
Or other approach with List.Contains, which generates sql query like
SELECT * FROM tblusers WHERE userid=1 AND status IN ('a','b');
var acceptedStatus = new List<string> { 'a', 'b' };
var result= _Repository.selectAll()
.Where(x => x.UserID == 1)
.Where(x => acceptedStatus.Contains(x.Status));
Notice that instead of && operator you can use another Where function and chain them. Can be more readable then fit all conditions in one line.
Try code:
var result =( from x in _Repository.selectAll()
where x.UserID==1 && (x.status=="a" || x.status=="B") select x);
another Solution
var result =( from x in _Repository.selectAll().where(c=>c.status=="a" || x.status=="B")
where x.UserID==1 select x);
could you please help me!
I have object list like:
item[0].title = apple
item[0].data.weight = 1
item[1].title = lemon
item[1].data = null
item[2].title = melon
item[2].data.weight = 3
I would like to sort it (ASC and DESC) by weight with null data.
I tried like this:
item.OrderBy(x => x.data == null).ThenBy(x => x.data.weight); // failed
item.Where(x => x.data != null).OrderBy(x => x.data.weight); // ok, but as result only two records
So how i can sort items and receive all results.
ASC at first should be data with null.
DESC at first data with max weight and null at the end of the list.
item.OrderBy(x => x.data == null).ThenByDescending(x => x.data == null ? 0 : x.data.weight);
I am assuming weight is an int, otherwise provide the default value based on type.
Given you're only shipping fruit, and not, say, light, you can treat items having null data as having weight 0. Alternatively, just pick any value that's lower than the possible, valid values in order to put the null items at the top when sorting ascendingly.
You can express that like this:
var ordered = item.OrderBy(x => x.data == null ? 0 : x.data.weight);
You could use something like this: (assuming C# 6 or above)
item.OrderBy(x => x.data?.weight ?? int.MinValue);
This makes use of the new C#6 null-conditional and null-coalescing operators - if you need something applicable in lower versions of C#, you can use a ternary operator, like this:
item.OrderBy(x => x.data != null ? x.data.weight : int.MinValue);
If it's possible that you could have x.data.weight being int.MinValue, then you would need to do something like what you were doing before, but the second linq method should make use of the above lambda/s.
You can do this a few ways, one way would be to have a value replacing the null values using ternary conditional operator on the order by or filtering out the items without a value and concatenating them to the enumerable after you've sorted the objects with values.
By conditionally providing a value for items with null
This is, in my opinion, the best way, and it performs better. You only enumerate over the collection once, versus the other method where you enumerate to determine if each element has a value then order, and then check for the items without a value
item.OrderBy(x => x.data != null ? x.data.weight : int.MinValue)
Filtering and then concatenating the items without a value
There are times where this could possibly be the better solution. One example would be if you want to use a different method for ordering the values when they are missing the property you are looking for.
item.Where(x => x.data != null)
.OrderBy(x => x.data.weight)
.Concat(item.Where(a=>a.data == null))
I am using MVC 4 and entity framework, I am retrieving emails from the server:
var data = db.Candidates.Where(c => ids.Contains(c.ID) && c.Email1 != null).Select(c => new { c.Email1, c.ID }).ToList();
My first question: Does LINQ allow me to return an empty string form the Email1 field if it is null, similar to SQL coalesce? (I would remove the null test from the where clause).
2nd question: what would be the easiest object to use (to replace the "var data =" if I wanted to get c.Name along with the Email1, then use both in a loop? Should I create a model for just 2 fields?
Thanks so much in advance for any insights.
My first question: Does LINQ allow me to return an empty string form the Email1 field if it is null, similar to SQL coalesce? (I would remove the null test from the where clause).
Yes, there is the ?? operator that works similar to the coalesce.:
new { Email1 = c.Email1 ?? "", c.ID } //String.Empty would be nicer, but i think it depends on EF version if you are allowed to use it.
For your second question, if this is the only place you are going to use them, then anonymous is pretty fine.
If you want to use this on other places, yes create an object just with two properties... That's the object's purpose after all. (or maybe a struct?)
Ask one question at a time.
2a. The Null Coalescence operator in C# is ??.
2b. This may or may not be converted by your Linq Provider into a database query.
Do it like this,
var data = db.Candidates
.Where(c => ids.Contains(c.ID))
.Select(c => new
{
Id = c.Id,
Email1 = c.Email1 ?? string.Empty,
Name = c.Name
});
foreach(var row in data)
{
var name = row.Name // etc...
}
If your Linq Provider does not support the ?? operator, put in a .ToList() and use linq-to-objects to perform the tranformation like this,
var data = db.Candidates
.Where(c => ids.Contains(c.ID))
.ToList() // <-- from here is Linq-To-Objects
.Select(c => new
{
Id = c.Id,
Email1 = c.Email1 ?? string.Empty,
Name = c.Name
});
I am trying to get the record from a database with the highest amount of days using a start and end date. I keep getting a System.Argument.Exception in the Entity.dll.
The error states:
{"DbArithmeticExpression arguments must have a numeric common type."}
Here is my LINQ statement:
var maxDaysTask = whseTasks.Where(x => x.CompDate != null && x.TaskDate != null).Max(x => ((DateTime)x.TaskDate - (DateTime)x.CompDate).TotalDays);
The CompDate(end date) and TaskDate(begin date) are both nullable datetimes. Any advice?
You cannot use subtraction in a query: the operator - is overloaded in .NET, but not in the SQL Server.
You can use SqlFunctions.DateDiff to achieve the effect that you are looking for:
var maxDaysTask = whseTasks
.Where(x => x.CompDate != null && x.TaskDate != null)
.Max(x => SqlFunctions.DateDiff("day", x.TaskDate, x.CompDate));
I would recommend using the built-in functions of Nullable<T> such as the HasValue property to check for null in this situation. Since these are nullable structs you usually can't access the internal values, which is why you are erroring. Make sure you use the Value property to get the actual DateTime struct
var maxDaysTask = whseTasks.Where(x => x.CompDate.HasValue && x.TaskDate.HasValue)
.Max(x => (x.TaskDate.Value - x.CompDate.Value).TotalDays);
How do I pass null as a value to a string (varchar) column from linq to sql? I'm trying to query the table where some rows have NULL for a column (say, Col_A) and others have "NotNull" (string) as value.
string s = null;
var query = (from r in context.Table1
where r.Col_A == s
select r).ToList();
This returns 0 rows. But if I set s to "NotNull", I get the rows back as expected.
Any pointers will be helpful.
There is an annoying bug, where the following can work differently in some cases:
where x.Foo == null
vs
where x.Foo == s
where s happens to be null at execution. Basically, in some use-cases, it can incorrectly end up using:
WHERE [x].[Foo] = #p3
with #p3 a null value, but clearly that is not sensible in ANSI compliant SQL.
I would suggest if you are doing a test where the parameter value might be null, special-case it and code the query with a literal null in the C#. I did have some code that would use an expression-visitor to apply this after-the-fact, but it is easier just to special-case null. So:
var query = // some core query
if(s == null) { query = query.Where(x => x.Foo == null); }
else { query = query.Where(x => x.Foo == s); }
have you tried DBNull.Value? That's .net's DB equivalent to null.