Linq query cannot convert double to double? - c#

I have two table:
AllPhonBills
PersonalNumbers
I want to query all records from first table where the numbers exist in PersonalNumbers table or list.
Bellow is my code:
var GetMyPersonalNumbers = db.MyPersonalNumContext.Where(i => i.EmployeeId == My_Emp_Id).Select(n => n.PersonalNumber).ToList();
var GetAllPersonalCalls = from c in db.MyAllPhoneBillContext
where GetMyPersonalNumbers.Contains(c.CALLED_NUMBER)
select c;
I get bellow error:
Argument 1: Cannot convert from 'double?' to 'double'
Can anyone tell me how to fix this error

The first argument is nullable double and it cannot be turned into double automatically.
You have to do something with nulls in the sequence of nullable types, for example:
IEnumerable<double> result =
sequence.Where(x => x.HasValue).Select(x => x.Value);

It is because in your database, you have a column of type double, but that datatype can be null. You cannot compare a nullable double to a non-nullable double. You might benefit from reading this msdn page

Either one variable in your code or a field in your DB is nullable (hence the '?'), that causes your problem.

I solved my problem by using a Join query bellow is my code:
var GetAllPersonalCalls = from c in db.MyAllPhoneBillContext
join p in db.MyPersonalNumContext on c.CALLED_NUMBER equals p.PersonalNumber
where c.CALLING_NUMBER == My_Number
where c.CALL_DATE.Year == currentYear
where c.CALL_DATE.Month == currentMonth
select new PhoneBillVM
{
CALLING_NUMBER = c.CALLING_NUMBER,
CALLED_NUMBER = c.CALLED_NUMBER,
CALL_DURATION = c.CALL_DURATION,
CustomTime = c.CALL_TIME.Hour + ":" + c.CALL_TIME.Minute + ":" + c.CALL_TIME.Second,
CALL_COST = c.CALL_COST,
CALL_DATE = c.CALL_DATE
};

Related

how to get a linq query result to int

below query return a single value eg 50. I want it be assign to int so I can do some calculation with that value. how can I do this
var LTLimit = from a in dbavailability.tACLicenseTypes
where a.License_Type == "Long Term"
select a.Limit;
string AST = "";
I'm not completely clear on what you're asking, but presumably the type of data returned by your Linq query is not int, and you want to convert it to int? If so, simply convert it to an int:
var LTLimit = (from a in dbavailability.tACLicenseTypes
where a.License_Type == "Long Term"
select a.Limit).ToList();
int LTLimitInt = 0
if (!int.TryParse(LTLimit.First(), out LTLimitInt))
{
Console.WritLine("LTLimit is not a number!")
}
Since you've updated your question, here's a solution to convert the returned number to an int, multiply it by 2, then convert the result to a string:
var LTLimit = (from a in dbavailability.tACLicenseTypes
where a.License_Type == "Long Term"
select a.Limit).ToList();
int LTLimitInt = 0;
string multipliedResultStr = string.Empty;
if (!int.TryParse(LTLimit.First(), out LTLimitInt))
{
Console.WritLine("LTLimit is not a number!")
}
else
{
multipliedResult = (LTLimitInt * 2).ToString();
Console.WriteLine(string.Format("Result is {0}, multipliedResult ));
}
Edit;
Corrected code to take first item from list.
The following code is one way to retrieve the first integer returned in your query:
var LTLimit = (from a in dbavailability.tACLicenseTypes
where a.License_Type == "Long Term"
select a.Limit).ToList();
int limit = LTLimit[0];
What is the return type of the query?
If the returned type is of another primative data type like a string, then you can try to convert it to an integer using :
var i = Convert.ToInt32(LTLimit);
Or using :
int.TryParse(LTLimit, out var i);
However, it would be better if the data was stored in the correct type in the first place.
You can use Sum() after where() for value of object property
like this bonus.Where(b => b.Id == x.key && b.RequiredScore.HasValue).Sum(b => b.RequiredScore.Value);

LINQ: Set a default value if navigation property is null

This is my current LINQ statement:
var results = from l in leads
select new MyObject
{
LeadID = l.LeadID,
SelectedProposalEngineerID = l.LeadContacts.Where(contact => contact.LeadContactTypeID == LeadContactType.ProposalEngineer).FirstOrDefault().ContactID
};
The trouble I'm having is that the last item is often null. So when I try to convert "results" to a List, I get
{"The cast to value type 'System.Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type."}
I don't want to make SelectedProposalEngineerID a nullable int, for problems that would cause down stream. How would I give it a value of 0 when it's null?
I have seen a LOT of other threads about this, but I can't seem to adapt any of their answers to this case.
Use DefaultIfEmpty extension method.
var results = from l in leads
select new MyObject
{
LeadID = l.LeadID,
SelectedProposalEngineerID =
l.LeadContacts.Where(contact => contact.LeadContactTypeID == LeadContactType.ProposalEngineer)
.Select(contact => contact.ContactID)
.DefaultIfEmpty(0)
.FirstOrDefault()
};
Nullable<int> ID;
var results = from l in leads
select new MyObject
{
LeadID = l.LeadID,
SelectedProposalEngineerID = (ID = l.LeadContacts.Where(contact => contact.LeadContactTypeID == LeadContactType.ProposalEngineer).FirstOrDefault().ContactID).HasValue ? ID.Value : 0;
};
A ternary operator should do the job. Assign the result to a variable, then if it's not null, cast the variable to int and return it, else return 0.

How to check DBNull value in Linq query results

I am using the below code and trying to group by Currency and Code. After this I am trying to loop through the result set.
But the issue is while looping through the results, at the end I am getting the below exception on the for each statement:
Object cannot be cast from DBNull to other types.
DataTable dt = new DataTable();
var result = from r in dt.AsEnumerable()
result r by new
{
currency = r.Field<String>("CURRENCY"),
Code = r.Field<String>("CODE")
}
into grp
select new
{
currency = grp.Key.currency,
Code = grp.Key.Code,
amount = grp.Sum(x => Convert.ToDouble(x["AMOUNT"]))
};
foreach (var obj in result)
{
String sCurr =obj.currency;
String Code = obj.Code;
string amount= obj.amount.ToString());
}
Please help me to resolve this issue.
Something like
amount = grp.Sum(x => Convert.ToDouble(x["AMOUNT"] == DBNull.Value ? 0 : x["AMOUNT"]));
If that is the line that is giving you the problem.
The way to find the number of CELLS with DBNulls for a specific column:
int numOfEmptyColA = MyDataTable.AsEnumerable().Where(p=>p.IsNull("ColA")).Count();
This:
amount = grp.Sum(x => Convert.ToDouble(x["AMOUNT"]))
will not work as you expect. If x["AMOUNT"] is DBNull.Value instead of a valid double, the conversion will fail with an exception. Instead, try:
amount = grp.Sum(x.Field<double?>("AMOUNT"))
if you expect that field to be a double. Sum will treat the null values as zero, per MSDN.
I'm not sure which one is getting the error, but you can can compare it to DBNull.Value like so.
String sCurr = obj.currency == DBNull.Value ? "" : obj.currency;

LINQ's WHERE clause where COLUMN may be null

I have a problem with making WHERE clause with LINQ. I tried to google it but I've only got answers on what to do if the external variable is the type of nullable integer... well, I've tried these methods the other way around (I have 0...1 relations in my dataset):
e.g.
int oldId = oldQuestion.id;
IEnumerable<possible_answer> possibleAnswersQuery =
from x in Mentor11Entities.possible_answers
where object.Equals(x.question_id, oldId)
select x;
List<possible_answer> possibleAnswers =
possibleAnswersQuery.ToList<possible_answer>();
or
int oldId = oldQuestion.id;
IEnumerable<possible_answer> possibleAnswersQuery =
from x in Mentor11Entities.possible_answers
where Convert.ToInt32(x.question_id ?? 0).Equals(oldId)
select x;
List<possible_answer> possibleAnswers =
possibleAnswersQuery.ToList<possible_answer>();
but I'm always getting the error that LINQ doesn't support certain functions... is there any way to get around the problem?
just use
where x.question_id != null && x.question_id == oldId
so your query should be:
IEnumerable<possible_answer> possibleAnswersQuery =
from x in Mentor11Entities.possible_answers
where x.question_id != null && x.question_id == oldId
select x;

error in Linq query

I have following Linq:
var ownerRegistryId = 731752693037116688;
var excludeTypes = new[]
{
"CA00", "CA01", "CA03", "CA04", "CA02",
"PA00", "PA01", "PA02", "PA03", "PA04"
};
var maxStateChangeMonth = 4;
var excludeStatusId = 999;
var includeMortgage = new[] { "CL10", "CL11", "PL10", "PL11" };
var sum = (
from account in context.Accounts
from owner in account.AccountOwners
where owner.AccountOwnerRegistryId == ownerRegistryId
where !excludeTypes.Contains(account.AccountType)
where account.StateChangeDate == null ||
(account.StateChangeDate.Month - DateTime.Now.Month)
<= maxStateChangeMonth
where includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage")
where account.AccountStatusId != excludeStatusId
select account.MinimumInstallment)
.Sum(minimumInstallment => Math.Abs(minimumInstallment));
but I get the error:
The cast to value type 'Decimal'
failed because the materialized value
is null. Either the result type's
generic parameter or the query must
use a nullable type.
this error comes as soon as I add this:
where (includeMortgage.Contains(account.AccountType) ||
account.AccountType.Contains("Mortgage"))
If I remove this from above query, it works.
The query is translation of following SQL:
SELECT Sum(ABS([Minimum Installment])) AS SumOfMonthlyPayments FROM tblAccount
INNER JOIN tblAccountOwner ON tblAccount.[Creditor Registry ID] = tblAccountOwner.
[Creditor Registry ID] AND tblAccount.[Account No] = tblAccountOwner.[Account No]
WHERE (tblAccountOwner.[Account Owner Registry ID] = 731752693037116688)
AND (tblAccount.[Account Type] NOT IN
('CA00', 'CA01', 'CA03', 'CA04', 'CA02', 'PA00', 'PA01', 'PA02', 'PA03', 'PA04'))
AND (DATEDIFF(mm, tblAccount.[State Change Date], GETDATE()) <=
4 OR tblAccount.[State Change Date] IS NULL AND ((tblAccount.[Account Type] IN ('CL10','CL11','PL10','PL11')) OR
tblAccount.[Account Type] LIKE 'Mortgage')) AND (tblAccount.[Account Status ID] <> 999)
I'd try to rewrite the last two lines of your query like so:
var sum = (
...
select account)
.Sum(a => Math.Abs(a.MinimumInstallment));
That's how I interprete this part of the exception "...or the query must use a nullable type". By using the projection select account.MinimumInstallment you have a non-nullable type, namely decimal which is the type of account.MinimumInstallment.
Not sure though, just a guess.
Edit
The problem might actually be the final assignment var sum = .... Since you don't specify the result type explicitely the compiler will here infer the type to decimal because MinimumInstallment is decimal. The query can actually return null when the selected recordset was empty so the cast to decimal is impossible.
So, let's help the compiler to infer the result type of the query to decimal?:
var sum = (decimal?)(from ... ) ?? 0;
(Replace from ... by your original query or maybe by my modified version above.)
Edit 2
OK, the first Edit didn't work (according to comment in another question). Indeed I could reproduce the issue in a similar example. But the following worked in my example:
var sum = (
...
select account)
.Sum(a => (decimal?)Math.Abs(a.MinimumInstallment))
.GetDefaultOrValue();
Try using:
Math.Abs((decimal)(minimumInstallment.HasValue ? minimumInstallment : 0));
How about:
Math.Abs((decimal)(minimumInstallment!= null ? minimumInstallment : 0));

Categories