I have three tables and they are linked like
grandparent -> parent -> child
categoryType - > Categories - > Menus
when I try to run following
return categoryTypes.Select(x =>
new CategoryTypeIndexModel
{
Id = x.Id,
Name = x.Name,
Categories = x.Categories.Count,
Items = x.Categories.Sum(m => m.Menus.Count())
});
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.
You are trying to count something that isn't there when Categories is null.
I believe what Habib recommend would technically work but you would still have to account for a null value after the fact.
I think the better solution would be to account for it in your linq directly by looking for null and providing a default
return categoryTypes.Select(x => new CategoryTypeIndexModel
{
Id = x.Id,
Name = x.Name,
Categories = (x.Categories == null) ? 0 : x.Categories.Count,
Items = (x.Categories == null) ? 0 : x.Categories.Sum(m => m.Menus.Count())
});
If Menus could ever be null you would also need to account for that in a similar fashion
Related
I am passing an array of integers to an API endpoint composed in a model such as:
public class SomeModel {
public IList<int> ints { get; set; }
}
My endpoint to hit is:
Get["/myobjects/{id:int}"] = _ =>
{
var ints = this.Bind<SomeModel>();
return myService.someMethod1((int)_.id, ints.Ints));
};
Then, when I want to query the object in the DB,
var count = context.ReadOnly<SomeModel>()
.Query(x => x.myId == id && // id is already defined
ints != null &&
ints.Contains(x.SomeModelId))
.Select(x => x.Id)
.Count();
I am using Entity Framework as an ORM.
Unable to create a null constant value of type 'System.Collections.Generic.IList`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral]]'.
Or I get:
Cannot compare elements of type 'System.Collections.Generic.IList`1[[System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral]'. Only primitive types, enumeration types and entity types are supported.
Only entity types, enumeration types or primitive types are supported in this context.
The exception states that it can't create a null constant value, but I am populating the array that is coming in - so I don't understand why it is throwing this error.
EDIT: The array of ints is not being bound and the list is null. Does anybody know how to correctly bind to the list?
Have in mind all that checks you are doing in the lamdba are inside the query this means EF most probably will try to evaluate them to SQL.
But what you are checking is a variable that is not a part of the query. When the case is this, you need to split the check for null outside the query.
var query = context.ReadOnly<SomeModel>().Query(x => x.myId == id);
if (ints != null) {
query = query.Where(x => ints.Contains(x.SomeModelId);
}
var count = query.Select(x => x.Id).Count();
If I understood well the business case, if ints is null, the whole query will evaluate to false, so you most probably will be satisfied to just checking if ints is null -> if true, the count is zero. Otherwise - query the database.
var count = 0;
if (ints != null)
{
count = context.ReadOnly<SomeModel>()
.Query(x => x.myId == id &&
ints.Contains(x.SomeModelId))
.Select(x => x.Id)
.Count();
}
I am using linq to Entities. I am trying to select a nullable Int field with below code but I am getting Exception
List<MyClass> myList = myContext.Accounts
.Where(x => x.ACCOUNT_TYPE_ID == 58 && x.IS_DELETED == 0)
.Select(x=> new PayorCode
{
Id = x.ID,
Payor = x.CODE_NUM + " - "+ x.DESCRIPTION
}).ToList();
In Accounts property CODE_NUM is of Nullable<global::System.Int32> .
I am getting the below exception
Unable to cast the type 'System.Nullable`1' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
How should I use the nullable field in Linq to Entites ? I tried with Convert.ToInt32 and object.Equals but both didn't worked.
Any help will be appreciated
Dealing with nullable ints in EF should be no different to dealing with them under normal circumstances. You can check that they have a value using .HasValue, you can read the value directly using .Value and you can null-coalesce using ??. Depending on what you want to happen in the case that this property is null, you should be able to do something along the lines of:
.Select(x=> new PayorCode
{
Id = x.ID,
Payor = x.CODE_NUM.HasValue
? x.CODE_NUM.Value + " - "+ x.DESCRIPTION
: "CODE_NUM Missing"
})
or perhaps:
.Select(x=> new PayorCode
{
Id = x.ID,
Payor = (x.CODE_NUM ?? "0") + " - "+ x.DESCRIPTION,
})
The class list "List" can't be used with the strongly type class list PayorCode referenced in your select. Either use a "var query = ..." along with PayorCode or if List is the same as PayorCode then substitute PayorCode with MyClass. So
.Select(x => new MyClass { ....}
Then answer 2 should work fine.
I have following code,
var applications = from a in applications1.Entities.ToList()
select new
{
name = a.Attributes["sia_name"].ToString(),
applicationId = a.Attributes["sia_applicationid"].ToString(),
isDraftMode = a.Attributes.Contains("sia_applicationmode") ? a.FormattedValues["sia_applicationmode"].ToString().ToLower() == "draft" ? true : false : false
};
in this code I have applications which contains name ,applicationid,and isdraftmode,
now I want to fetch applicationid from var application so that I can pass it to session
how can it be achive
Session["ApplicationID"]=applications
do it like
Session["ApplicationID"]=applications.Select(m => m.applicationId).First();
it would give you first applicationId. If you want to select applicationId based on condition then you can do it like
Session["ApplicationID"]=applications.Select(m => m.applicationId).First(x => x.property == condition);
and for all the applicationid do it like
Session["ApplicationID"]=applications.Select(m => m.applicationId).ToList();
So you have a query which selects multiple properties in an anonymous type and you need to select one specific property from it to write it into session?
Session["ApplicationID"] = applications
.Select(x => x.applicationId)
.ToList(); // i would "materialize" it in a collection to avoid side effect due to lazy evaluation
or do you instead want to get a specific item from it, for example via sia_name?
var sia = applications.FirstOrDefault(x => x.sia_name == "InsertName");
if(sia != null)
Session["ApplicationID"] = sia.applicationId;
... But it's not null.
FYI - Many threads exist on this error, but none that I've seen using an anonymous type.
I'm Getting an odd InvalidOperationException in a Linq query.
message: "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."
The confusing thing is that it's erroring when creating an anonymous type:
var workstepid = 484,449;
var wsData = ion.xWorkSteps
.Where(w => w.WorkStepId == workstepId)
.Select(w => new
{
w.WorkStepId,
w.ServiceId,
w.Service.TitleId,
w.Service.Title.OrderId,
w.Service.Title.AltTitleId
}).SingleOrDefault();
In LinqPad this particular query runs just fine and the workstepId used returns an integer value for each property of the anonymous type. So why a casting error when there is no null value for any property!?
FYI, the last property AltTitleId is a nullable int, and the other properties are ints.
Also, this code was written weeks ago and I didn't get this error until today. Is something funky w/ my EF?
Edit: SOLVED
We use soft-delete in our db's, setting deleted records to Acive=0.
It turns out that there is a property set in EF on the edmx tables filtering out inactive records (filter for Active=1). Naturally, this wouldn't effect Linqpad which gives me the expected result, but since this was an older record I was testing, the title record (Service.Title) had been marked Active=0 and was therefore returning null.
Thanks to everyone for the help.
var workstepid = 484,449;
var wsData = ion.xWorkSteps
.Where(w => w.WorkStepId == workstepId)
.Select(w => new
{
w.WorkStepId.Value,
w.ServiceId.Value,
w.Service.TitleId.Value,
w.Service.Title.OrderId.Value,
w.Service.Title.AltTitleId.Value
}).SingleOrDefault();
Hi you need to add .Value in your int data type to accept null value. hope this helps
If w.WorkStepId is nullable, try setting your variable as...
int? workstepid = 484449;
I suppose, the problem is in your SingleOrDefault().
I suppose that you get 0 records:
var workstepid = 484,449;
var len = ion.xWorkSteps
.Where(w => w.WorkStepId == workstepId)
.Length();
And then the anonymouse type must be replace by Default (this is what SingleOrDefault do), but there is no default for your anonymous type.
Try to change it to:
var wsData = ion.xWorkSteps
.Where(w => w.WorkStepId == workstepId)
.Select(w => new
{
w.WorkStepId,
w.ServiceId,
w.Service.TitleId,
w.Service.Title.OrderId,
w.Service.Title.AltTitleId
})
.Take(1)
.ToArray();
May be there are no Service/Title/Order id somewhere, but if it declared as int anonymous type expect int (not nullable), but from database it returns null.
Try to rewrite as :
var workstepid = 484,449;
var wsData = ion.xWorkSteps
.Where(w => w.WorkStepId == workstepId)
.Select(w => new
{
WorkStepId = (int?)w.WorkStepId,
ServiceId = (int?)w.ServiceId,
TitleId = (int?)w.Service.TitleId,
OrderId = (int?)w.Service.Title.OrderId,
w.Service.Title.AltTitleId
}).SingleOrDefault();
My entity NewsItem has a nullable foreign key property: LibraryID of type int?.
My issue is when I query the property and compare it with any value except null, I get exceptions.
Initially my code was:
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid);
but it gives me no results at all, no matter what lid is.
So, I tried:
var results = context.NewsItems
.Where(n => n.LibraryID.Equals(lid));
gives exception:
Unable to create a constant value of type 'System.Object'. Only primitive types or enumeration types are supported in this context.
and then I tried:
var results = context.NewsItems
.Where(n => lid.Equals(n.LibraryID));
and got:
Unable to cast the type 'System.Nullable`1' to type 'System.Object'. LINQ to Entities only supports casting EDM primitive or enumeration types.
and this:
var results = context.NewsItems
.Where(n => object.Equals(lid, n.LibraryID));
gives same exception as the last one.
Now I was desperate, so I tried to complicate stuff (like other forums suggested, for example here):
var results = context.NewsItems
.Where(n => (lid == null ? n.LibraryID == null : n.LibraryID == lid));
but still getting same exception.
So... any SIMPLE workarounds?
How about
var results = context.NewsItems
.Where(n => lid.HasValue ? lid.Value == n.LibraryId.Value : (!n.LibraryId.HasValue) );
Hmm, that first snippet should work. I've used nullables like that many times. First thing I'd do is a sanity check just to make sure LibraryID is really int? and not long? or similar.
Other than that, you can try this:
var results = context.NewsItems
.Where(n => (lid.HasValue ? n.LibraryID == lid.Value : !n.LibraryID.HasValue));
Or to avoid the ?: within the query:
var results = lid.HasValue
? context.NewsItems.Where(n => n.LibraryID == lid.Value)
: context.NewsItems.Where(n => !n.LibraryID.HasValue);
It seems that EF does not find the correct operator overload. Therefore it produces wrong results if you set lid = null.
Use linq to objects by adding AsEnumerable() to your query and everything is fine:
var results = context.NewsItems.AsEnumeryble().Where(n => n.LibraryID == lid);
According to the MSDN docs (which I finally found), .Where() will only filter your collection. If you want to see if there are actually results, resolve by lazily executing the filtered query with .ToList(), GetEnumerator, or enumerating the collection with foreach;
This method is implemented by using deferred execution. The immediate
return value is an object that stores all the information that is
required to perform the action. The query represented by this method
is not executed until the object is enumerated either by calling its
GetEnumerator method directly or by using foreach in Visual C# or For
Each in Visual Basic.
http://msdn.microsoft.com/en-us/library/bb534803.aspx
int? lid = ...
var results = context.NewsItems
.Where(n => n.LibraryID == lid).ToList();
var results = context.NewsItems
.Where(n => n.LibraryID.HasValue && n.LibraryID.Value == lid.Value );
edit:
Previous filter was based on my understanding that you wanted to filter to entires having a particular value. Updated will filter to null or value.
var results = context.NewsItems
.Where(n => !n.LibraryID.HasValue || n.LibraryID.Value == lid.Value );