Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Member is "not supported in LINQ to Entities"

So I am new to C#, LINQ, and MVC. I am trying to get a list of Ages, but it says

The specified type member 'Age' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.

For a previous tutorial, they use this exact same logic, except they check a string, not an int (Age). Why is this giving me a fit, and how can I fix it?

public ActionResult SearchIndex(string ageValue, string searchString)
{
    if (!string.IsNullOrEmpty(ageValue))
    {
         var AgeList = new List<string>();
         var AgeListQry = from d in db.Actors orderby d.Age select d.Age.ToString();
         AgeList.AddRange(AgeListQry.Distinct());
    }
    // other stuff
}

I want to learn what is going on, so that I can avoid this in the future!

Entity Model code

public class Actor
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public DateTime BirthDate { get; set; }
        public int Age
        {
            get { 
                return (int)(DateTime.Now - BirthDate).TotalDays / 365; 
            }

        }
        public decimal NetValue { get; set; }
    }
    public class ActorDBContext : DbContext
    {
        public DbSet<Actor> Actors { get; set; }
    }
like image 629
Austin Avatar asked Dec 26 '22 09:12

Austin


2 Answers

As mentioned in the comments, you can't call ToString() in a Linq to Entities query. Instead do it like this:

var AgeList = new List<string>();
//retrieve as whatever type Age is, no conversion in SQL Server
var AgeListQry = (from d in db.Actors orderby d.Age select d.Age).ToList();
//convert them after the fact, using Linq to Objects
AgeList.AddRange(AgeListQry.Select(a => a.ToString()).Distinct());

EDIT

I saw your latest update that does show that Age is not a database column. You are then required to do something like this (assuming BirthDate is properly mapped):

var AgeList = new List<string>();
//retrieve BirthDate from SQL Server and use ToList() to get it to run immediately
var AgeListQry = (from d in db.Actors orderby d.BirthDate select d.BirthDate).ToList();
//convert them after the fact, using Linq to Objects
AgeList.AddRange(AgeListQry.Select(bd => ((int)(DateTime.Now - bd).TotalDays / 365).ToString()).Distinct());

Linq to Entities maps your expressions to SQL statements and there is nothing for it to map to when you use your Age property. Instead, you need to get what you can from SQL Server (BirthDate) and then do the translation to Age yourself. You could replace the inline code with a method call like this if you'd rather:

AgeList.AddRange(AgeListQry.Select(bd => CalculateAge(bd)).Distinct());
//...
private string CalculateAge(DateTime birthday)
{
   return ((int)(DateTime.Now - bd).TotalDays / 365).ToString();
}
like image 167
Sven Grosen Avatar answered Jan 10 '23 09:01

Sven Grosen


You haven't the Age in you DB scheme and it is impossible to convert LINQ to DB query. You must order the Age collection in client side or add calculated column to your table.

like image 36
Hamlet Hakobyan Avatar answered Jan 10 '23 09:01

Hamlet Hakobyan