Could not resolve property for Average linq to NHibernate mapped object - linq

I have code that calculate average number of days from date opened to date closed.
When i run the expression using Linq and lambda expression i get error as follows:
Error message: could not resolve property: DateClosed.DateCreated of:
TestProject.LegalWork
where code is:
var result = Repository.All
.Where(x => x.DateClosed != null)
.Average(x => ((DateTime)x.DateClosed - x.DateCreated).TotalDays);
How ever when i run this using loop and filter on condition only, eveything work fine.
int number= 0;
decimal totalDays = 0;
foreach (LegalWork legalWork in Repository.All.Where(x => x.DateClosed != null))
{
totalDays += (decimal)((DateTime)legalWork.DateClosed - legalWork.DateCreated).TotalDays;
number++;
}
return (totalDays == 0 || numberOfLegalWork ==0 ) ? 0 : Convert.ToDecimal(totalDays/numberOfLegalWork);
What is wrong in Linq and Lambda version?

I'm sure you can't call to:
x.DateClosed - x.DateCreated
or givenDate.TotalDays in linq2nhibernate, because you should call a specific function of DateTime which is not part of linq2nhibernate it's part of .net framework and it doesn't implemented in linq2nhibernate, but your current error message says another thing, to solve ur problem currently u can do:
var result = Repository.All.Where(x => x.DateClosed != null).ToList()
.Average(x => ((DateTime)x.DateClosed - x.DateCreated).TotalDays);
if there is problem with above code, please insert ur class definition,
but sure it's not a best solution, it's better to write a stored procedure and call it.

Related

LINQ to Entities does not recognize the method Double Round(Double, Int32, System.MidpointRounding) method

I've tried the below LINQ Query in Linqer it is working fine but it is giving the below error while i tried with C#
from IHeal_Mnt_Tickets in iHealEntities.iHeal_Mnt_Tickets
where
Tickets.Active == 1 &&
Tickets.MntID == 1 &&
Tickets.InsertedOn >= fromdate &&
Mnt_Tickets.InsertedOn <= todate &&
(new string[] { "Resolved", "Assigned" }).Contains(Tickets.status)
group Tickets by new {
Tickets.Instance
} into g
select new {
Instance = g.Key.Summus_Instance,
Assigned = (Int64?)g.Count(p => p.iHealID != null),
resolved = (System.Int64?)g.Sum(p => (p.status == "Resolved" ? 1 : 0)),
domain = (System.Int64?)g.Sum(p => (p.status == "Assigned" ? 1 : 0)),
iHeal_Closure = (Decimal?)Math.Round((Double)(Double)g.Sum(p => (p.iHeal_Cur_status == "Resolved" ? 1 : 0)) * 1.0 / (Double)g.Count(p => p.iHealID != null) * 100, 2, MidpointRounding.AwayFromZero)
};
The error is
"LINQ to Entities does not recognize the method 'Double Round(Double, Int32, System.MidpointRounding)' method, and this method cannot be translated into a store expression."
Not everything that's supported in the BCL has a direct equivalent in SQL. Given that this is the final part of the query, the simplest approach would be to just write a query which fetched all the data you need without rounding etc, and then transform that data into your preferred format using a local query:
var dbQuery = from item in source
where filter
select projection;
// The AsEnumerable() part is key here
var localQuery = from item in dbQuery.AsEnumerable()
select complicatedTransformation;
Using AsEnumerable() effectively just changes the compile-time type... so that the Select call is Enumerable.Select using a delegate rather than Queryable.Select using an expression tree.
I would hope that you could make the final transformation much simpler than your current approach though - things like (Double)(Double) really aren't necessary... and any time you convert from double to decimal or vice versa, you should question whether that's necessary or desirable... it's generally better to stick to either binary floating point or decimal floating point, rather than mixing them.

LINQ to Entities does not recognize the method 'System.Collections.Generic.List`1[System.Int32]

I have the following error:
LINQ to Entities does not recognize the method
'System.Collections.Generic.List`1 [System.Int32] get_st_past_enrollment_success()'
method, and this method cannot be translated into a store expression.
This is caused by the following linq
IEnumerable<subject> _subjects = (from subject in context.subjects
where
subject.enrollments.Count() < subject.sj_max_enrollment
&& subject.sj_availability == true
&& !this.get_st_past_enrollment_success().Contains(subject.sj_subject_id)
select subject);
get_st_past_enrollment_success() returns a List:
public List<int> get_st_past_enrollment_success()
{
return this.enrollments.Where(e => e.em_enrolled == false && e.em_result >= 50).Select(e => e.em_subject_id).ToList();
}
What am i doing wrong here?
Your query itself contains the method call - and Entity Framework doesn't know what to do with that. Try extracting the list fetch to before the query:
var enrollments = get_st_past_enrollment_success();
var _subjects = from subject in context.subjects
where subject.enrollments.Count() < subject.sj_max_enrollment
&& subject.sj_availability
&& !enrollments.Contains(subject.sj_subject_id)
select subject;
Also note that get_st_past_enrollment_success violates .NET naming conventions - that won't affect whether the code works, but it'll look odd to other developers who are used to the normal conventions.

Set Null if no Results Returned EntityFramework

I get a Word from the database and printout its "Text" using ViewBag in my ASP.NET MVC3 EntityFramework project.
ViewBag.ManagementSystems = db.Words.Where(w => w.WordBaseID == 1 && w.LanguageID == lang).FirstOrDefault().Text;
However, if no results are returned, I got null exception and program crashes. What is the simplest and best way of printing nothing if no results are returned?
Solutions I know of:
1- Surround with if's or try-catch blocks
2- Use
var query = "SELECT Text FROM Words WHERE WordBaseID = {0} AND LanguageID = {1}";
ViewBag.ManagementSystems= db.Database.SqlQuery<string>(query, 1, lang).FirstOrDefault();
I propose:
ViewBag.ManagementSystems = db.Words.Where(w => w.WordBaseID == 1 && w.LanguageID == lang)
.Select(x => x.Text).FirstOrDefault();

Conversion error with Entity and Linq

I got the error
cannot implicity convert type 'System.Linq.IQueryable<EntityNetimoveis.San_Imovel>' to 'EntityNetimoveis.San_Imovel' An Explicit conversion exists (are you missing a cast ?)
This occurs when I try the following code
EntityNetimoveis.San2011Entities db = new EntityNetimoveis.San2011Entities();
EntityNetimoveis.San_Imovel im = db.San_Imovel.Where(a => a.Credenciada_Id == 10);
What type of conversion I have to do ?
EntityNetimoveis.San_Imovel im = db.San_Imovel.Where(a => a.Credenciada_Id == 10);
The type of im is an IQueryable<EntityNetimoveis.San_Imovel> because you are running a where query and there might be more than one result. If you want the first result matching your query you should use .FirstOrDefault(). Try changing you code as:
EntityNetimoveis.San_Imovel im = db.San_Imovel.FirstOrDefault(a => a.Credenciada_Id == 10);
If you want to return more than one entity and process them, lets say using a foreach loop, then you need to change the type of the return value to IEnumerable<Netimoveis.San_Imovel>. See the following example:
IEnumerable<EntityNetimoveis.San_Imovel> ims = db.San_Imovel.Where(a => a.Credenciada_Id == 10);
The you can use the following:
foreach(var im in ims) {
// your code goes here
}
If the lambda can return more than one record:
var imList = db.San_Imovel.Where(a => a.Credenciada_Id == 10).ToList();

Linq 2 SQL Sum using lambda and handling nulls

When using sum with lambda in Linq to SQL using the following code:
int query = (from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f).Sum(x => x.Rate);
I get the following error:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
. You have to make sure x.Rate is an int, and not an int? (an int that accepts null as a value).
. If the query has no elements, .Sum won't do anything and will return null. Choose a default value, let's say 0.
var query = from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f;
int result = query.Any()
? query.Sum(x => x.Rate ?? 0) // use the ?? if x.Rate is an "int?".
: 0; // default value you can choose.
I would break the int.Parse(ticket.ToString()) onto its own line to isolate that parse from the Linq for debugging.
We don't know whether that is throwing the exception or if one of the RDetails.Rate values is null. Is it indeed a Nullable<int>?
If RDetails.Rate is a Nullable<int>, then you could ...Sum(x => x.Rate ?? 0) and avoid the exception.

Resources