Link to home
Start Free TrialLog in
Avatar of innovasoft
innovasoft

asked on

FirstOrDefault() in Where-Statement (nhibernate, linq)

Hi everybody

I got this project-class with a list of status (already in the right order)

public class Project
    {

        public virtual int Id { get; set; }
        public virtual IList<ProjectStatus> Status { get; set; }
    }

public class ProjectStatus
    {
        public virtual int Id { get; set; }
        public virtual Project Project { get; set; }
        public virtual int Type { get; set; }
        public virtual DateTime Creationdate { get; set; }
    }

Open in new window


the mapping is like this

public ProjectMapping()
        {
            Table("Projects");
            Id(x => x.Id, "ProjectId");
            HasMany(x => x.Status).Table("ProjectStatus").KeyColumn("ProjectId").OrderBy("Creationdate DESC").Cascade.All();
            
        }

public ProjectStatusMapping()
        {
            Table("ProjectStatus");
            Id(x => x.Id, "ProjectStatusId");

            Map(x => x.Creationdate);
            Map(x => x.Typ);

            References<Project>(x => x.Project, "ProjectId");
        }

Open in new window


Now I would like to search a project where the current status (the first in the list) has Type = 2. I thought I could easily handle this like this:

_projectRepository.Table.Where(p => p.Status.FirstOrDefault() != null && p.Status.Type == 2).FirstOrDefault();

Open in new window


But this just throws following exception (unfortunately I only got the german version of it)

Eine Ausnahme vom Typ "Antlr.Runtime.NoViableAltException" wurde ausgelöst. [.Count[OSS.Domain.Project](.Where[OSS.Domain.Project](NHibernate.Linq.NhQueryable`1[OSS.Domain.Project], Quote((g, ) => (Equal(Convert(.FirstOrDefault[OSS.Domain.ProjectStatus](g.Status, ).Type.Id), p1))), ), )]

Does anyone know how to fix this?

Thank you very much!
Avatar of innovasoft
innovasoft

ASKER

I figured out, that I can get a status with Type==2 by using "Any()"

_projectRepository.Table.Where(p => p.Status.Any(s => s.Type == 2)).ToList();

Open in new window


But this just returns any status with Type==2 and not only the latest one. So I tried this

_projectRepository.Table.Where(p => p.Status.Any(s => s.Type == 2 && s.Id == p.Status.Max(max => max.Id))).ToList();

Open in new window


But this fails again :(
Avatar of kaufmed
Well this logic shouldn't even compile:

_projectRepository.Table.Where(p => p.Status.FirstOrDefault() != null && p.Status.Type == 2).FirstOrDefault();

Open in new window


...and even if it had it wouldn't have produced expected results, unless there was only one element in the collection. The reason is that the "p.Status.FirstOrDefault()" would return the first element of the collection--regardless of what Type it had--and the "p.Status.Type == 2"--barring the fact that the syntax is incorrect--would be independent of the earlier "p.Status.FirstOrDefault()".

Does you newest query (the bottom one) raise an exception, or does it just not return expected results?
thank you for your answer!

ups... I made a mistake when I put the code in the textfield (i changed some variable-names so that you can understand it better). But it actually looks like this

_projectRepository.Table.Where(p => p.Status.FirstOrDefault() != null && p.Status.FirstOrDefault().Type == 2).FirstOrDefault();

Open in new window


I'm sorry for that

and this still throws the same exception as I wrote in the first post
I'm not sure I can be of further assistance since I am not familiar with NHibernate. When looking up the details of a NoViableAltException it seems the causes vary. From what I can see, it sounds like you might be using an invalid construct as far as NHibernate is concerned. To me, it seems akin to using foreign functions in LINQ-to-SQL (e.g. trying to use DateTime.Parse within a query where there is no equivalent SQL function to DateTime.Parse). The only thing in the query that seems plausible is the FirstOrDefault, but I think it would be weird that that particular function would be unsupported.

Certainly hold out for responses from the other experts  : )
ASKER CERTIFIED SOLUTION
Avatar of innovasoft
innovasoft

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I didn't really get a nice solution. This one is only a workaround and I wanted to let you all know about that