Null value cannot be assigned - LINQ query question - linq

I have the following LINQ query:
DataClassesDataContext dc = new DataClassesDataContext();
var query = from contact in dc.Contacts
select new
{
ContactId = contact.ContactId,
LastName = contact.LastName,
FirstName = contact.FirstName,
Addresses = contact.Addresses,
Phones = contact.Phones,
DOB = contact.BirthDate,
LastNote = contact.Notes.Max(n => n.Created), //this line causes the error
Status = contact.ContactStatus.ContactStatusName,
EmailAddress = contact.Emails
};
The line where I get the maximum created date for the notes collection causes the following exception to be thrown:
Exception: The null value cannot be assigned to a
member with type System.DateTime which
is a non-nullable value type.
How do I write the query to allow null values into the LastNote field? The DOB field is defined as DateTime? and has not problem handling nulls.

Think I figured it out.
If I cast the maximum note value to a nullable DateTime it seems to eliminate the exception. The following change worked for me:
LastNote = (Nullable<DateTime>)contact.Notes.Max(n => n.Created)
As others have pointed out, it can also be written using the shorthand notation for a nullable DateTime as follows:
LastNote = (DateTime?) contact.Notes.Max(n => n.Created)

Rewrite that line as:
LastNote = (DateTime?) contact.Notes.Max(n => n.Created),

LastNote = contact.Notes.Max(n => (DateTime?)n.Created)
Couldn't find this on the net so i hope this helps others.

In VB is something like:
LastNote = CType(contact.Notes.Max(n => n.Created), Global.System.Nullable(Of Date))
I think...

You could do that, or you could alter your database schema so that the column 'Created' does not allow nulls.
The scenario is arising because one of the rows comes back with a null value for Created.
If the db didn't allow nulls, the scenario would never occur.

Related

linq Command not getting the answer for DB

i have a table(UserQuestions) in my DB(WebSiteUsers) which contains QuestionID field as a Primary key and QuestionContext field which holds the Questions that are asked as its value.
Now i want to have a textBox that show me the QuestionContext Value by getting QuestionID.
I used these linq commands and none of them bring me the correct answer :
string Questioncontext = new WebSiteUsersEntities().UserQuestions.Where(p => p.QuestiuonID.ToString() == QuestionID).Select(p => new { p.QuestionContext}).ToString();
string Questionx = (from q in new WebSiteUsersEntities().UserQuestions where q.QuestiuonID.ToString() == QuestionID select q.QuestionContext).ToString();
QuestionCntxt.Text = Questionx;
the outcome is like this :
SELECT
[Extent1].[QuestionContext] AS [QuestionContext]
FROM [dbo].[UserQuestion] AS [Extent1]
WHERE CAST( [Extent1].[QuestiuonID] AS nvarchar(max)) = #p__linq__0
I guess your QuestionID variable is of type string, while the database column is of type int.
So rather than using
q.QuestiuonID.ToString() == QuestionID
criteria inside the query, convert the variable to int and use that as criteria.
Also ToString just gives you the SQL query text, not the result. Use ToList if you expect more than one result or FirstOrDefault if you expect zero or one results:
var questionID = int.Parse(QuestionID);
string Questioncontext = new WebSiteUsersEntities().UserQuestions
.Where(p => p.QuestiuonID == questionID)
.Select(p => p.QuestionContext)
.FirstOrDefault();
Note that I also changed the select to return directly QuestionContext string rather than anonymous object having QuestionContext property.

LINQ - To Get Year from Date which is of Type String

I have this LINQ query:
hdms = from t in db.HOLIDAY
join t1 in db.EMPLOYEE on t.UPDATED_BY equals t1.EMP_CODE
where
t.HOLIDAY_NAME == searchtext &&
t.DOH.Value.Year == 2016
orderby
t.DOH
select new HOLIDAYDETAILS
{
HOLIDAY_NAME = t.HOLIDAY_NAME,
DOH = t.DOH,
EMP_NAME = t1.EMP_NAME
};
While executing this, below error occurs:
'string' does not contain a definition for 'Value' and no extension method 'Value' accepting a first argument of type 'string' could be found (are you missing a using directive or an assembly reference?)
Error comes under Value in t.DOH.Value.Year = 2016.
Here type of t.DOH is string and value is 2016-04-14
I have also tried this one:
hdms = from t in db.HOLIDAY
where
DateTime.ParseExact(t.DOH, "yyyy-MM-dd", CultureInfo.InvariantCulture).Year == DateTime.Now.Year
orderby
t.DOH
select new HOLIDAYDETAILS
{
DOH = t.DOH
};
Now got this error:
LINQ to Entities does not recognize the method 'System.DateTime ParseExact(System.String, System.String, System.IFormatProvider)' method, and this method cannot be translated into a store expression.
Is there any other way to convert string to date type in LINQ?
Since DOH is of type string you could use StartsWith to check if the string starts with 2016.
where
t.HOLIDAY_NAME == searchtext &&
t.DOH.StartsWith("2016")
A better option would be to change your datatype of DOH to DateTime/DatetTime?, to get better support when working with date and time values. Then you can leave your query as it is.
You can parse DateTime from string like:
DateTime.ParseExact(t.DOH, "yyyy-MM-dd", CultureInfo.InvariantCulture)
Then you can get year value using [DateTimeVariable].Year

Dynamic Linq on DataTable error: no Field or Property in DataRow, c#

I have some errors using Linq on DataTable and I couldn't figure it out how to solve it. I have to admit that i am pretty new to Linq and I searched the forum and Internet and couldn't figure it out. hope you can help.
I have a DataTable called campaign with three columns: ID (int), Product (string), Channel (string). The DataTable is already filled with data. I am trying to select a subset of the campaign records which satisfied the conditions selected by the end user. For example, the user want to list only if the Product is either 'EWH' or 'HEC'. The selection criteria is dynaically determined by the end user.
I have the following C# code:
private void btnClick()
{
IEnumerable<DataRow> query =
from zz in campaign.AsEnumerable()
orderby zz.Field<string>("ID")
select zz;
string whereClause = "zz.Field<string>(\"Product\") in ('EWH','HEC')";
query = query.Where(whereClause);
DataTable sublist = query.CopyToDataTable<DataRow>();
}
But it gives me an error on line: query = query.Where(whereClause), saying
No property or field 'zz' exists in type 'DataRow'".
If I changed to:
string whereClause = "Product in ('EWH','HEC')"; it will say:
No property or field 'Product' exists in type 'DataRow'
Can anyone help me on how to solve this problem? I feel it could be a pretty simple syntax change, but I just don't know at this time.
First, this line has an error
orderby zz.Field<string>("ID")
because as you said, your ID column is of type int.
Second, you need to learn LINQ query syntax. Forget about strings, the same way you used from, orderby, select in the query, you can also use where and many other operators. Also you'll need to learn the equivalent LINQ constructs for SQL-ish things, like for instance IN (...) is mapped to Enumerable.Contains etc.
With all that being said, here is your query
var productFilter = new[] { "EWH", "HEC" };
var query =
from zz in campaign.AsEnumerable()
where productFilter.Contains(zz.Field<string>("Product"))
orderby zz.Field<int>("ID")
select zz;
Update As per your comment, if you want to make this dynamic, then you need to switch to lambda syntax. Multiple and criteria can be composed by chaining multiple Where clauses like this
List<string> productFilter = ...; // coming from outside
List<string> channelFilter = ...; // coming from outside
var query = campaign.AsEnumerable();
// Apply filters if needed
if (productFilter != null && productFilter.Count > 0)
query = query.Where(zz => productFilter.Contains(zz.Field<string>("Product")));
if (channelFilter != null && channelFilter.Count > 0)
query = query.Where(zz => channelFilter.Contains(zz.Field<string>("Channel")));
// Once finished with filtering, do the ordering
query = query.OrderBy(zz => zz.Field<int>("ID"));

Linq Query Message: Specified cast is not valid

Following are the columns name and its data type:
TemplateName string
TaskName string
AvgDays string (but contains int values)
my LINQ query:
DataTable newTable = new DataTable();
newTable = (from r in table.AsEnumerable()
group r by r.Field<string>("TemplateName") into templates
let totalDays = templates.Sum(r => r.Field<int>("AvgDays"))
from t in templates
group t by new
{
TemplateName = templates.Key,
TaskName = t.Field<string>("TaskName"),
TotalDays = totalDays
} into tasks
select new
{
tasks.Key.TemplateName,
tasks.Key.TaskName,
AvgDays = tasks.Sum(r => r.Field<int>("AvgDays")),
tasks.Key.TotalDays
}).CopyToDataTable();
I am getting error after execution of query. Error is "Specified cast is not valid.".
Please let me know where am I doing wrong.
I guess Field<int> causes the problem, because the field is not really an int. As you said before, it's a string.
Try following
AvgDays = tasks.Sum(r => int.Parse(r.Field<string>("AvgDays"))),
Field<T> does not perform some magic transformation between different types. It's implemented like that:
return (T)((object)value);
In practice there is a little bit more code, but logic is the same. It just tried to cast your value to desired type, and as you probably know, casting string to int does not work.

LINQ: Nullable object must have a value.

Let me preface this by saying I'm a novice with LINQ, and that this is code that I didn't originally write but am trying to fix. I've done a lot of research on this error, but I haven't found anything helpful yet. In fact, this error sort of makes my head spin. Anyway...
I have a LINQ query that is selecting some data from three SharePoint lists. Here it is:
private void loadPEGrid(int id)
{
dc = new SpEntityDataContext(SPContext.GetContext(this.Context).Web.Url);
EntityList<ProductDocumentMapItem> dMaps = dc.GetList<ProductDocumentMapItem>("Product Document Map");
object mappedItems = null;
mappedItems = from m in dMaps
join p in dc.PEProducts on m.ProductID.Value equals p.Id.Value
join d in dc.ProductDocuments on m.DocID.Value equals d.Id.Value
where m.ProductID.Value == id && m.ProductType == "PE"
select new {
p.Grade,
d.Path,
d.DocumentType,
d.Title,
d.Name,
Language = d.Language.Title,
m.Id,
DocId = m.DocID };
GridViewProducts.KeyFieldName = "Id";
GridViewProducts.DataSource = mappedItems;
GridViewProducts.DataBind();
}
The following fields are nullable:
m.ProductID
m.DocID
d.DocumentType
m.Id
When I debug, none of this throws an error, but when the page loads it does:
System.InvalidOperationException: Nullable object must have a value
Does this mean that one of the fields I'm selecting is null, or one of the join fields? Having checked the data, I don't think this is the case. Let me know if you need any more info from me.
System.InvalidOperationException: Nullable object must have a value
This exception is thrown when you are trying to get Value property of nullable type. So, that means one or more of following is true:
At least one of objects in dMaps has property ProductID equal to null
At least one of objects in dMaps has property DocID equal to null
At least one of objects in dc.PEProducts has property Id equal to null
At least one of objects in dc.ProductDocuments has property Id equal to null
Exception raised not by query

Resources