Aamir
Aamir

Reputation: 1757

Unable to cast the type 'System.Int64' to type 'System.Object'. LINQ to Entities only supports casting Entity Data Model primitive types

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

Answers (3)

Aamir
Aamir

Reputation: 1757

Resolved

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

jcvandan
jcvandan

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

Servy
Servy

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

Related Questions