Reputation: 1757
I have created a EF 4 & C# to get some data. I am using Linq. Its as follows:
public List<object> GenerateCallTrackingReport(int startRowIndex, int maximumRows, int createdByID)
{
var query = from c in this.ObjectContext.CallLogs
select new
{
CallLogID = c.CallLogID,
DomainName = c.CallDomain.FullName,
CreatedByID = c.CreatedByID,
CreatedBy = c.CreatedByUser.FirstName + " " + c.CreatedByUser.LastAccessIPN,
CalledOn = c.CallDate,
IssueResolutionTime = c.IssueResolutionTime,
CallType = c.CallType.FullName,
CallDescription = c.CallDescription,
CustomerName = (c.CustomerID > 0 ? c.Customer.FirstName + " " + c.Customer.LastAccessIPN : c.TempCaller.FirstName + " " + c.TempCaller.LastName),
CustomerEmail = (c.CustomerID > 0 ? c.Customer.Email : string.Empty),
CustomerResponse = c.Response.FullName,
IsPending = c.IsPending,
NeedFurtherContact = c.NeedFurtherContact
};
if (createdByID > 0)
query = query.Where(c => c.CreatedByID == createdByID);
if (maximumRows > 0)
query = query.Skip(startRowIndex).Take(maximumRows);
return query.ToList<object>();
}
This is causing the following error:
Unable to cast the type 'System.Int64' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types.
Any Idea y am i getting this error??
Thanks
Upvotes: 9
Views: 14540
Reputation: 1757
I had two issues, each of them would cause this error:
1. I was accessing NULLABLE entity properties without checking if they have value or not. Say CustomerID is NULLABLE, so my query became something like this!
var query = from c in this.ObjectContext.CallLogs
select new
{
CallDescription = c.CallDescription,
CustomerID = c.CustomerID.HasValue ? c.CustomerID.Value : 0,
CustomerName = c.CustomerID.HasValue ? c.Customer.Name : ""
};
if (maximumRows > 0)
query = query.Skip(startRowIndex).Take(maximumRows);
return query.ToList<object>();
So just check any null value by its HasValue property before accessing it (2nd line in select portion).
2. I Was also trying to convert integer to string within the select statement. So i just decided that conversion in HTML instead of directly doing it here. This solved my issues.
Hope this helps someone!
Upvotes: 5
Reputation: 14314
First, I wouldn't retrieve the whole table, then do queries on the full dataset in C# as you are doing here. Chaining linq to entities methods like this will make it faster - massively so when you get huge datasets:
this.ObjectContext.CallLogs
.Where(c => c.CreatedByID == createdByID)
.Skip(startRowIndex)
.Take(maximumRows)
.Select(new
{
CallLogID = c.CallLogID,
DomainName = c.CallDomain.FullName,
CreatedByID = c.CreatedByID,
CreatedBy = c.CreatedByUser.FirstName + " " + c.CreatedByUser.LastAccessIPN,
CalledOn = c.CallDate,
IssueResolutionTime = c.IssueResolutionTime,
CallType = c.CallType.FullName,
CallDescription = c.CallDescription,
CustomerName = (c.CustomerID > 0 ? c.Customer.FirstName + " " + c.Customer.LastAccessIPN : c.TempCaller.FirstName + " " + c.TempCaller.LastName),
CustomerEmail = (c.CustomerID > 0 ? c.Customer.Email : string.Empty),
CustomerResponse = c.Response.FullName,
IsPending = c.IsPending,
NeedFurtherContact = c.NeedFurtherContact
})
.ToList();
Second, I don't know the exact problem, but creating a list of dynamic objects like this isn't really a good idea. Create a CallLogModel
class with the properties you are putting in the object like this:
.Select(new CallLogModel
{
CallLogID = c.CallLogID,
DomainName = c.CallDomain.FullName,
CreatedByID = c.CreatedByID,
CreatedBy = c.CreatedByUser.FirstName + " " + c.CreatedByUser.LastAccessIPN,
CalledOn = c.CallDate,
IssueResolutionTime = c.IssueResolutionTime,
CallType = c.CallType.FullName,
CallDescription = c.CallDescription,
CustomerName = (c.CustomerID > 0 ? c.Customer.FirstName + " " + c.Customer.LastAccessIPN : c.TempCaller.FirstName + " " + c.TempCaller.LastName),
CustomerEmail = (c.CustomerID > 0 ? c.Customer.Email : string.Empty),
CustomerResponse = c.Response.FullName,
IsPending = c.IsPending,
NeedFurtherContact = c.NeedFurtherContact
})
Upvotes: 0
Reputation: 203821
Once you get to the ToList
call you want to be performing it in C#, not in the database. Use AsEnumerable
as a way of saying, "Stop doing this stuff in the database, do it in C#."
Add that right before the ToList
at the end so that everything else is done on the database.
Upvotes: 5