how do I pass null to int column in linq - linq

How do we assign null value to int column in LINQ.
eg.
SQLDBDataContext sqlD = new SQLDBDataContext();
var result = from p in sqlD.loadsRadius(Convert.ToInt32(Request["radius"]), .....
here if Request["radius"] is null gives an error.
I could pass 0 via this but I need to change in many already existing procedures.
Thanks in advance.
Anil

You need to case the int to a null, eg:
var result = from p in sqlD.loadsRadius(string.IsNullOrEmpty(Request["radius"]) ? (int?)null : int.Parse(Request["radius"]);

If the exception is a FormatException, my guess is that the value returned by Request["radius"] is actually the string "null". If Request["radius"] actually returned null, Convert.ToInt32() would return zero. You may try using using int.TryParse() to avoid the exception.

as suggested by Codechef..
int radius = -1;
int.TryParse(Request["radius"],out radius)
if(radius > 0) // you can remove this clause if you don't want this
{
SQLDBDataContext sqlD = new SQLDBDataContext();
var result = from p in sqlD.loadsRadius(radius)
}

Look into nullable types: Here.

You could use ?? operator like this:
Convert.ToInt32(Request["radius"] ?? "0")
If Request["radius"] equals to null, it will return "0" instead.

Related

Linq: Nullable Object must have Value

My query is as follows:
int ID = db.Q_Table.Find(item.PassedInID).ID;
I already found a solution for my issue, however i am wondering why i must write it like so
1.
Nullable(int) ID = db.Q_Table.Find(item.PassedInID).ID;
2.
db.Q_Table.Where(w => w.PassedInID== item.PassedInID).Select(s => s.ID ).SingleOrDefault();
It wouldn't let me put int int he < in the above code -.-...
I am curious why i have to code it to a nullable int? I really didn't want to code it like 2nd solution because its more code :). Yes i have made sure there are values in the database and from the below image you can see my database doesn't accept nulls.
Thanks for any answers
There is a difference between int and Nullable<int> or int?, you can't directly assign a Nullable<int> to int (Nullable<T>), Consider:
int? x = 123;
int y = x; //This would be an error
But you can use null-coalescing operator
int? x = 123;
int y = x ?? 0;
Now for your case, your ID seems to be a mapped to column in database which allows null. That will map to C# Nullable<int>, if you want to assign the result to an int you can do:
int ID = db.Q_Table.Find(item.PassedInID).ID ?? 0;
That will give your variable the value of ID or 0 if it is null.
ID is not an int but rather a Nullable<int> (or short form int?).
This is typically the case when the underlying database column is nullable.
There is also no < operator defined on an int?. If you want to do that, you have to check for the presence of a value first:
db.Q_Table.Where(w => w.PassedInID.HasValue && w.PassedInID.Value == item.PassedInID)
.Select(s => s.ID ).SingleOrDefault();
that's probably because db.Q_Table.Find returns a nullible int.
you can probably also do the following if you wanted to
int? ID = db.Q_Table.Find(item.PassedInID).ID;
I guess you could do something like the following, it is a little less code:
int? t;
int ID = (t = db.Q_Table.Find(item.PassedInID).ID) == null ? -1 : t;
Of course, now you will have to handle -1 ID as a special case later in your code. I expect you just want a nullable int.

Linq 2 SQL Sum using lambda and handling nulls

When using sum with lambda in Linq to SQL using the following code:
int query = (from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f).Sum(x => x.Rate);
I get the following error:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
. You have to make sure x.Rate is an int, and not an int? (an int that accepts null as a value).
. If the query has no elements, .Sum won't do anything and will return null. Choose a default value, let's say 0.
var query = from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f;
int result = query.Any()
? query.Sum(x => x.Rate ?? 0) // use the ?? if x.Rate is an "int?".
: 0; // default value you can choose.
I would break the int.Parse(ticket.ToString()) onto its own line to isolate that parse from the Linq for debugging.
We don't know whether that is throwing the exception or if one of the RDetails.Rate values is null. Is it indeed a Nullable<int>?
If RDetails.Rate is a Nullable<int>, then you could ...Sum(x => x.Rate ?? 0) and avoid the exception.

linq to entity framework: something like isnull

I have:
a = b.Sum(...) + c.Sum(...)
where b,c are entities.
The problem is: when at least one of (b.Sum(...), c.Sum(...)) is null then a will be null. I'd like null be treated as 0. How would I do this?
At least in LINQ2SQL you can cast to int? manually and then handle the null case
a = ((int?)b.Sum(...) + c.Sum(...)).GetValueOrDefault();
maybe something like this
a = ( b.Sum(...) + c.Sum(...)) ?? 0;
now if the expression is null, a will be 0;
I think you could use null coelesce for this:
a = (b.Sum(..) + c.Sum(...)) ?? 0;
NOTE: unchecked syntax! not sure what your sums are doing!
Have a look at the following MSDN article: http://msdn.microsoft.com/en-us/library/ms173224.aspx

How to make a linq Sum return null if the summed values are all null

I have a LINQ query that looks like this...
var duration = Level3Data.AsQueryable().Sum(d => d.DurationMonths);
If all the d.DurationMonths values are null the Sum returns 0. How can I make the Sum return null if all the d.DurationMonths are null? Or do I need to run a separate query first to eliminate this situation before performing the sum?
Along with the previous suggestion for an extension method - you could use a ternary operator...
var duration = Level3Data.AsQueryable().Any(d => d.DurationMonths.HasValue)
? Level3Data.AsQueryable().Sum(d => d.DurationMonths)
: null;
You can use Aggregate to provide custom aggregation code :
var items = Level3Data.AsQueryable();
var duration = items.Aggregate<D,int?>(null, (s, d) => (s == null) ? d.DurationMonths : s + (d.DurationMonths ?? 0));
(assuming the items in Level3Data are of type D)
var outputIndicatorSum = (from OutputIndicatorTable in objDataBaseContext.Output_Indicators
where OutputIndicatorTable.Output_Id == outputId
select (int?)OutputIndicatorTable.Status).Sum();
int outputIndicatorSumReturn = Convert.ToInt32(outputIndicatorSum);
return outputIndicatorSumReturn;
You can explicitly type cast non-nullable varaible into nullable type.
i.e, select (int?)OutputIndicatorTable.Status).Sum();
Using Sum alone, this is impossible. As you indicated in your question, you will need to check for this situation before you call Sum:
var q = Level3Data.AsQueryable();
var duration = q.All(d => d.DurationMonths == null)
? null
: q.Sum(d => d.DurationMonths);
If you would like the result without two queries try:
var duration = Level3Data.AsQueryable().Sum(d => (double?)d.DurationMonths);
If you want zero instead of null as the result of this query use:
var duration = Level3Data.AsQueryable().Sum(d => (double?)d.DurationMonths) ?? 0;

Linq to SQL: .FirstOrDefault() not applicable to select new { ... }

I just asked this question. Which lead me to a new question :)
Up until this point, I have used the following pattern of selecting stuff with Linq to SQL, with the purpose of being able to handle 0 "rows" returned by the query:
var person = (from p in [DataContextObject].Persons
where p.PersonsID == 1
select new p).FirstOrDefault();
if (person == null)
{
// handle 0 "rows" returned.
}
But I can't use FirstOrDefault() when I do:
var person = from p in [DataContextObject].Persons
where p.PersonsID == 1
select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode };
// Under the hood, this pattern generates a query which selects specific
// columns which will be faster than selecting all columns as the above
// snippet of code does. This results in a performance-boost on large tables.
How do I check for 0 "rows" returned by the query, using the second pattern?
UPDATE:
I think my build fails because I am trying to assign the result of the query to a variable (this._user) declared with the type of [DataContext].User.
this._user = (from u in [DataContextObject].Users
where u.UsersID == [Int32]
select new { u.UsersID }).FirstOrDefault();
Compilation error: Cannot implicitly convert type "AnonymousType#1" to "[DataContext].User".
Any thoughts on how I can get around this? Would I have to make my own object?
Why can you keep doing the samething? Is it giving you an error?
var person = (from p in [DataContextObject].Persons
where p.PersonsID == 1
select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode }).FirstOrDefault();
if (person == null) {
// handle 0 "rows" returned.
}
It is still a reference object just like you actual object, it is just anonymous so you don't know the actual type before the code is compiled.
Update:
I see now what you were actually asking! Sorry, my answer no longer applies. I thought you were not getting a null value when it was empty. The accepted response is correct, if you want to use the object out of scope, you need to create a new type and just use New MyType(...). I know DevEx's RefactorPro has a refactoring for this, and I think resharper does as well.
Call .FirstOrDefault(null) like this:
string[] names = { "jim", "jane", "joe", "john", "jeremy", "jebus" };
var person = (
from p in names where p.StartsWith("notpresent") select
new { Name=p, FirstLetter=p.Substring(0,1) }
)
.DefaultIfEmpty(null)
.FirstOrDefault();
MessageBox.Show(person==null?"person was null":person.Name + "/" + person.FirstLetter);
That does the trick for me.
Regarding your UPDATE: you have to either create your own type, change this._user to be int, or select the whole object, not only specific columns.
if (person.Any()) /* ... */;
OR
if (person.Count() == 0) /* ... */;
You can still use FirstOrDefault. Just have
var PersonFields = (...).FirstOrDefault()
PersonFields will be be null or an object with those properties you created.

Resources