Error in MVC Linq - c#

I have Linq query in MVC
obj_CCM.TeamName = (from c in db.Team_Master
where c.Id != TeamId
select new TypeTeam
{
TeamID = c.Id,
TeamName = c.TeamName
}
).ToList();
Session["TeamId"] = obj_CCM.TeamName.Count > 0 ? Convert.ToInt32(obj_CCM.TeamName[0].TeamID) : -1;
I facing below error :
The cast to value type 'Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.

I guess issue is at this line:
TeamID = c.Id
In your Team_Master table, the Id column must be Nullable so it is returning null but property TeamID in TypeTeam is defined as int and can't hold null values. So you need to either disallow your Id column in database to accept null values or make the TeamID property as nullable of integer.
public int? TeamID{ get; set; }
Also, as a side note, your query is returning List<TypeTeam> but you are storing that in obj_CCM.TeamName, either this is a typo or you may have defined TeamName of type List<TypeTeam>.

Check first, if Session["TeamId"] != null and then do the converting

Related

Unable to create a null constant value of type XX.XX Only entity types, enumeration types or primitive types are supported in this context

I am using EF. A parent table CUSTOMER and a relational table CUSTOMER_PAYMENT_TERM.
I want to get result with following approach.
var result = (from x in EntitiesContext.CUSTOMERS
select new
{
CustomerId = x.CUSTOMERID,
PaymentTerms = x.PAYMENTTERMID > 0 ?
new PaymentTermBo
{
PaymentTermId = (decimal)x.PAYMENTTERMID,
Discount = (decimal)x.CUSTOMER_PAYMENT_TERM.DISCOUNT
}
: null,
}).ToList();
I got following error for above code.
Unable to create a null constant value of type PaymentTermBo Only entity types, enumeration types or primitive types are supported in this context.
I really want to use this approach "Want to put if condition for object to fill".
But when use following approach, it works.
var result = (from x in EntitiesContext.CUSTOMERS
select new
{
CustomerId = x.CUSTOMERID,
PaymentTerms = new PaymentTermBo
{
PaymentTermId = x.PAYMENTTERMID > 0 ? (decimal)x.PAYMENTTERMID : 0,
Discount = x.PAYMENTTERMID > 0 ? (decimal)x.CUSTOMER_PAYMENT_TERM.DISCOUNT : 0
}
}).ToList();
But i want to use first approach as i have complex tables and many columns, do not want to fill all the values by putting if condition for each value as it will slow down the query.

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.

LINQ and nullable parameter

I have a nullable field in DB and nullable parameter in model. I try the following LINQ to Entities query:
EditPersonViewModel model = (from i in db.Person
where i.PersonID == id.Value
select new EditPersonViewModel()
{
PersonID = i.PersonID,
Fullname = i.Fullname,
Comment = i.Comment,
Username = (i.UserId != null) ? i.AspNetUsers.UserName : String.Empty,
// this is parameter has type "int?"
PersonStatusID = (i.PersonStatus!=null) ? i.PersonStatus.PersonStatusID : null
}).FirstOrDefault();
I get the compilation error:
Error 1 Type of conditional expression cannot be determined because
there is no implicit conversion between 'int' and ''
it works fine with
Username = (i.UserId != null) ? i.AspNetUsers.UserName : String.Empty,
but does not work with "int?" type. Why and how to do it correctly?
Documentation of Conditional Operator says:-
Either the type of first_expression and second_expression must be the
same, or an implicit conversion must exist from one type to the other.
Since i.AspNetUsers.UserName & String.Empty are string types its working fine for you. Now, your problem is self explanatory because null cannot be casted to integer type, you need this instead:-
PersonStatusID = (i.PersonStatus!=null) ? i.PersonStatus.PersonStatusID : 0;
Or the other way around if you need that as Nullable of integer:-
PersonStatusID = (i.PersonStatus!=null) ? (int?)i.PersonStatus.PersonStatusID : null;
PersonStatusID should be of type int? in this case.

new blank, non null anonymous type

I need to insert a new blank, but non null anonymous type into a list of other anonymous types returned by a linq query. Is that possible? All I can get are nulls
var something =
( from a in x.As
where x != null
join b in x.Bs
on a.key equals b.key
select new
{
a.prop1,
a.prop2,
b.prop1,
b.prop2,
b.prop3
}).ToList();
// insert blank
//something.InsertRange(0, something.DefaultIfEmpty());
//something.InsertRange(0, something.Take(0));
//?
I don't know of a way to do it in a single query since the default for an anonymous type is null. What I would do is pre-create a "default" item and append it if necessary:
var blank = new {
prop1 = default(string), // can't use null
prop2 = default(string), // because the type cannot be inferred
prop3 = default(string),
prop4 = default(string)
};
var something = /*...*/.ToList();
if(!something.Any())
something.Add(blank);
Note that as long as the field names match (in name and type) blank will be of the same anonymous type as the one created by the Linq query.

The property 'x' on 'tblX' could not be set to a 'null' value. You must set this property to a non-null value of type 'Int16'

List<tblX> messages = (from x in db.tblX where x.msg_id == id_id
|| x.name == firstName select x).ToList();
I get the error:
The property 'x' on 'tblX' could not be set to a 'null' value. You must set this property to a non-null value of type 'Int16'.
I have a property msg_blocked in db, which is nullable and integer. I know that I need to make a conversion, but I don't use it or need it anywhere in my linq.
Seems like your class definition for tblX doesn't match the database representation, so either modify your class to accept a nullable value, or just project out the required fields:
List<tblX> messages = (from x in db.tblX
where (x.msg_id == id_id || x.name == firstName)
select new tblX
{
//required fields
msg_id = x.msg_id,
name = x.name,
...
}).ToList();
Addendum: The reason you run into this problem is behind the scenes when you
select x
this is translated into a
select new tblX
which projects into all its available fields. The code provided is more explicit and specifies which fields to query for and then project into.
List<tblX> messages = (from x in db.tblX
where (x.msg_id == id_id || x.name == firstName) &&
x.msg_blocked != null
select x).ToList();

Categories