Cannot convert from IQueryable <decimal,Project1,Model> to IQueryable<Project1,Model> - c#

What does this error mean?
My error is:
Cannot implicitly convert type 'System.Linq.IQueryable<System.Linq.IGrouping<decimal,Project1.Domain.Models.DepartmentBreakdownReport>>' to 'System.Linq.IQueryable<Project1.Domain.Models.DepartmentBreakdownReport>'. An explicit conversion exists (are you missing a cast?)
I would like to know what it is in order for me to be able to fix it. It only happens when I add a LINQ GroupBy onto my results.
public IQueryable<DepartmentBreakdownReport> GetDepartmentBreakdownBySupplierIDAndReviewID(int ClientID, int? SupplierID, int? ReviewID) {
return (from d in Db.Details
join h in Db.Headers
on new { d.ClientID, d.ClaimID }
equals new { h.ClientID, h.ClaimID }
where d.ClientID == ClientID && h.SupplierID == SupplierID
join sd in Db.SuppDepts
on new { a = d.ClientID, b = d.CategoryID ?? 0 }
equals new { a = sd.ClientID, b = sd.CategoryID }
join r in Db.Reviews
on new { h.ClientID, h.ReviewID }
equals new { r.ClientID, r.ReviewID }
join rp in Db.ReviewPeriods
on new { a = r.ClientID, b = r.ReviewPeriodID ?? 0 }
equals new { a = rp.ClientID, b = rp.ReviewPeriodID }
where r.ReviewID == ReviewID
join su in Db.Suppliers
on new { h.ClientID, h.SupplierID }
equals new { su.ClientID, su.SupplierID }
select new DepartmentBreakdownReport {
DepartmentName = sd.DepartmentName,
SumOfAmount = d.Amount,
SupplierID = h.SupplierID,
ReviewID = h.ReviewID,
ReviewName = rp.ReviewPeriodName,
SupplierName = su.SupplierName,
ClientID = d.ClientID
}).GroupBy(r=>r.Amount);
}

What does this error mean?
Your return type is IQueryable<DepartmentBreakdownReport> yet you are attempting to return a IGrouping<decimal,Project1.Domain.Models.DepartmentBreakdownReport>
When you call .GroupBy you change the return type to IGrouping rather than IQueryable, it also introduces the decimal as part of the IGrouping expression (Which is the amount variable you are grouping by).
To fix it you can simply change the method signature to:
public IGrouping<decimal,Project1.Domain.Models.DepartmentBreakdownReport> GetDepartmentBreakdownBySupplierIDAndReviewID(int ClientID, int? SupplierID, int? ReviewID)

To me, the method name GetDepartmentBreakdownBySupplierIDAndReviewID would imply:
Firstly that the method return type would be something like this, assuming types of int for SupplierId and ReviewId :
IGrouping<Tuple<int, int>, IQueryable<DepartmentBreakdownReport>>
GetDepartmentBreakdownBySupplierIDAndReviewID(...)
Secondly that the return should be on a final projection something like:
select new DepartmentBreakdownReport { ... })
.GroupBy(r => new Tuple<int, int>(r.SupplierID, r.ReviewID));

Related

How to handle null tables in linq left join

I'm writing linq query as below: -
from eventDetails in CurrentDataContext.EventCarriers
join eventlog in CurrentDataContext.EventLogCarriers on eventDetails.EventID equals eventlog.EventId into hhh
from eventlog in hhh.DefaultIfEmpty()
join quiz in CurrentDataContext.QuizCarriers on eventDetails.EventID equals competition.EventId into aaa
from quiz in aaa.DefaultIfEmpty()
where eventDetails.EventID == eventId && eventDetails.EventStatusId == 1 && eventlog.CreatedBy == userId
group new { eventDetails, quiz, eventlog } by new
{
eventDetails.EventID,
eventDetails.Name
} into g
select new VenueModel
{
Name = g.Key.Name,
EventId = g.Key.EventID,
StartDate = g.Key.StartDate,
EndDate = g.Key.EndDate,
EventDescr = g.Key.EventDescr,
EventIconPath = g.Key.EventIconPath,
EventImagePath = g.Key.EventImagePath,
Prizes = (from a in g.Select(a => a.competitions)
group a by new
{
a.PrizeId,
a.PrizeIconPath,
a.CompetitionDescr,
a.PrizeImagePath,
a.EndDate,
a.StartDate,
a.Name,
a.EventId,
a.StatusId
} into x
select new CCompetitionModel
{
PrizeDescrption = x.Key.PrizeDescr,
PrizeIconPath = x.Key.PrizeIconPath,
PrizeId = x.Key.PrizeId,
}).ToList(),
}).FirstOrDefault();
But I'm getting an error like The cast to value type 'System.Int32' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
//Declare your class property nullable.
//For example, if you are getting start date null from database, then your property will be like following.
public class Event
{
public DateTime? StartDate{get; set;}
//add other properties of this class here..
}

Odata How to return anonymous type from a function

I want to return an anonymous type from a function in an Odata driver. But I'm getting a 406 error.
This is my function in the WebApiConfig:
builder.Function("TestFunction")
.Returns<Object>();
This is my method in the Odata controller
[HttpGet]
[ODataRoute("TestFunction")]
public IHttpActionResult TestFunction()
{
var created = (from RI in db.RequestInstance
join RVI in db.RequestVersionInstance on RI.ActualRequestVersionInstanceID equals RVI.RequestVersionInstanceID
join RS in db.RequestState on RVI.RequestStateID equals RS.RequestStateID
where RI.ClientUserID == userDepartmentId && RVI.RequestStateID == 1
group RI by new { RI.RequestInstanceID, RS.Name, RS.Color } into C
select new DashBoardFilter()
{
Name = C.Key.Name,
Color = C.Key.Color,
Quantity = C.Count()
}
).Single();
var select= (from RI in db.RequestInstance
join RVI in db.RequestVersionInstance on RI.ActualRequestVersionInstanceID equals RVI.RequestVersionInstanceID
join RS in db.RequestState on RVI.RequestStateID equals RS.RequestStateID
where RI.ClientUserID == userDepartmentId && RVI.RequestStateID == 2
group RI by new { RI.RequestInstanceID, RS.Name, RS.Color } into C
select new DashBoardFilter()
{
Name = C.Key.Name,
Color = C.Key.Color,
Quantity = C.Count()
}
).Single();
return Ok(new { Created = created, Select = select});
}
I hope you can help me
Thanks

The cast to value type 'System.Int32' failed because the materialized value is null.

I'm trying to return a list of results, however. Whenever there are no results, I receive the error message which I have posted above. However, it's strange because whenever I add the variable q instead of the return, it just returns no results instead and is fine with this. I would prefer to do it the way which I am currently doing it right now, does anybody know what is wrong with the query? Whenever I run it in LINQPad it works completely fine.
public IQueryable<ClaimNumberReport> GetClaimsByClaimNumber(int ClientID, int ClaimID) {
/*var q = */ return (from d in camOnlineDb.Details
join a in camOnlineDb.Areas
on new { a = d.ClientID, b = d.AreaID ?? 0 }
equals new { a = a.ClientID, b = a.AreaID }
where d.ClientID == ClientID
join r in camOnlineDb.Reasons
on new { a = d.ClientID, b = d.ReasonID ?? 0 }
equals new { a = r.ClientID, b = r.ReasonID }
join sd in camOnlineDb.SuppDepts
on new { a = d.ClientID, b = d.CategoryID ?? 0 }
equals new { a = sd.ClientID, b = sd.CategoryID } into sdd
from sd in sdd.DefaultIfEmpty()
join h in camOnlineDb.Headers
on new { d.ClientID, d.ClaimID}
equals new { h.ClientID, h.ClaimID }
where h.ClaimID == ClaimID
join su in camOnlineDb.Suppliers
on new { h.ClientID, h.SupplierID }
equals new {su.ClientID, su.SupplierID }
join cp in camOnlineDb.ClaimPacks
on new { h.ClientID, h.ClaimID }
equals new { cp.ClientID, cp.ClaimID }
join rev in camOnlineDb.Reviews
on new { h.ClientID, h.ReviewID }
equals new { rev.ClientID, rev.ReviewID }
join revp in camOnlineDb.ReviewPeriods
on new { a = rev.ClientID, b = rev.ReviewPeriodID ?? 0 }
equals new { a = revp.ClientID, b = revp.ReviewPeriodID }
join st in camOnlineDb.Statuses
on new { a = d.ClientID, b = d.StatusID ?? 0 }
equals new { a = st.ClientID, b = st.StatusID }
join stcm in camOnlineDb.StatusCategoryMappings
on new { st.ClientID, st.StatusID }
equals new { stcm.ClientID, stcm.StatusID }
join stc in camOnlineDb.StatusCategories
on new { stcm.StatusCategoryID }
equals new { stc.StatusCategoryID }
where stc.StatusCategoryTypeID == 1
select new ClaimNumberReport {
TypeID = d.ClaimTypeID,
CPAttached = cp.FileName,
ReviewPeriodName = revp.ReviewPeriodName,
ClaimID = d.ClaimID,
Line = d.ClaimLine,
AccountNo = su.AccountNo,
SupplierName = su.SupplierName,
Amount = d.Amount,
Status = st.StatusDesc,
DateSent = d.DateSent,
DayOS = d.DaysOS,
NominalPeriod = d.NominalPeriod,
SLInvoiceNo = d.SLInvoiceNo,
Area = a.AreaDesc,
DebitRef = d.DebitFile,
DebitDate = d.JournalDate,
DeductDate = d.DeductDate,
StatusCategoryID = stc.StatusCategoryID,
StatusCategoryDesc = stc.StatusCategoryDesc,
APLReason = r.ReasonDesc,
ClientID = d.ClientID,
DeptNo = sd.DepartmentID,
DeptName = sd.DepartmentName,
Agreed = d.Agreed
});
/*return q;*/
}
This error is caused by a situation where the query result type has a column/property of non-nullable type but the generated query results in a NULL value.
This could be considered a bug or not. It is hard to see what the L2S team should have done differently here. I think they should have added a better error message. This bug is insidious because it sometimes only strikes in production under unusual data...
Your left join (sd) seem not to match and one of the sd.* properties that you select must be an int. Solve that like this:
DeptNo = (int?)sd.DepartmentID, //Cast to nullable
d.CategoryID ?? 0
What are you doing here? This seems to be a way to make the join compile. It's better to use:
join r in camOnlineDb.Reasons
on new { a = d.ClientID, b = (int?)d.ReasonID }
equals new { a = r.ClientID, b = (int?)r.ReasonID }
This cast makes the anonymous type signatures compatible. The generated SQL should now be faster. If you say x ?? 0 that converts to COALESCE(x, 0) which can prevent index use and such.

Initialize var value to null for strongly typed

I am trying to do something like the following:
I am not sure how to initialize teh restultCLList as I cannot set it to null.
var resultCLlist = null;
if (RdoStatus.SelectedValue == "Incomplete")
{
resultCLList = (from ms in db.ver_ServiceReport
join gc in db.map_Sit
on ms.SiteId equals gc.SiteID
where gc.CompanyId == companyId
select new ServiceReport
{
VerificationId = ms.VerificationId,
SiteId = ms.SiteId,
}
).ToList();
}
else
{
resultCLList = (from ms in db.ver_ServiceReport
join gc in db.map_Sites
on ms.SiteId equals gc.SiteID
where gc.CompanyId == companyId
select new ServiceReport
{
VerificationId = ms.VerificationId,
SiteId = ms.SiteId,
SiteName = gc.SiteName,
TimeStamp = ms.TimeStamp,
EntryDate = ms.EntryDate,
Supplier = ms.Supplier
}
).ToList();
}
Why don't you use List<ServiceReport> instead of var ?
You can't initialize var to a null value, because null is not a type itself.You can cast it to object but it won't be safe.var is useful if you don't know the returning type of the expression on the right side, or if the type name is too long.In this case you know the type, so simply don't use var.

Send a query to a model repository

Please help. I am new in ASP.NET MVC and I am trying to send a query to a repository but it gives me an error:
Errr 3 Cannot implicitly convert type
'System.Collections.Generic.List' to
'System.Collections.Generic.IList'. An
explicit conversion exists (are you missing a cast?)
I am using a a Schema Class with only the columns that I need. This is the code that I am using for the repository.
public class SSGridRepository : SSGridIRepository
{
private DataClassesSSDataContext db;
public SSGridRepository()
{
db = new DataClassesSSDataContext();
}
public IList<SSQuerySchema> ListAll()
{
var SSQuery = (from HISTORies in db.HISTORies
join SSes in db.SSes on HISTORies.WO equals SSes.WO
join SSCUSTOMs in db.SSCUSTOMs on SSes.WO equals SSCUSTOMs.WO
join StatusTables in db.StatusTables on new { STATUS = SSes.STATUS } equals new { STATUS = StatusTables.Status }
join StatusTable_1 in db.StatusTables on new { OLDSTATUS = HISTORies.OLDSTATUS } equals new { OLDSTATUS = StatusTable_1.Status }
join StatusTable_2 in db.StatusTables on new { NEWSTATUS = HISTORies.NEWSTATUS } equals new { NEWSTATUS = StatusTable_2.Status }
where
HISTORies.OLDSTATUS == "m" &&
HISTORies.NEWSTATUS == "n" &&
HISTORies.ACTION == "Change Job Status" &&
HISTORies.OLDSTATUS != HISTORies.NEWSTATUS &&
HISTORies.DATE.Value.Year == Convert.ToDateTime(DateTime.Now).Year ||
HISTORies.OLDSTATUS != HISTORies.NEWSTATUS &&
HISTORies.NEWSTATUS == "m" &&
HISTORies.ACTION == "Checked In Work Order" &&
HISTORies.DATE.Value.Year == Convert.ToDateTime(DateTime.Now).Year
orderby
HISTORies.DATE
select new
{
HISTORies.WO,
SSes.TITLE,
SSes.DESCRIPT,
SSCUSTOMs.CUSTNAME,
SSes.STAKER,
HISTORies.USER,
SSes.STATUS,
HISTORies.OLDSTATUS,
HISTORies.NEWSTATUS,
CURRENT_STATUS = StatusTables.Description,
OLD_STATUS = StatusTable_1.Description,
NEW_STATUS = StatusTable_2.Description,
HISTORies.DATE.Value.Month,
HISTORies.DATE
}).Distinct();
return SSQuery.ToList();
}
}
In you Linq you do this:
select new {
HISTORies.WO,
SSes.TITLE,
SSes.DESCRIPT,
SSCUSTOMs.CUSTNAME,
SSes.STAKER,
HISTORies.USER,
SSes.STATUS,
HISTORies.OLDSTATUS,
HISTORies.NEWSTATUS,
CURRENT_STATUS = StatusTables.Description,
OLD_STATUS = StatusTable_1.Description,
NEW_STATUS = StatusTable_2.Description,
HISTORies.DATE.Value.Month,
HISTORies.DATE
}
Which is a dynamic type so it wont match you return type of List<SSQuerySchema>
Try initializing the type you have specified in your Linq and set the properties of course.
select new SSQuerySchema {
// initialize all properties here
}
You're trying to return an IList<SSQuerySchema> but your actual return type is IList<dynamic> (Your not selecting SSQuerySchema's but an anonymous type.
You should either make the return type of the function IList<dynamic> or modify your select to create new instances of SSQuerySchema

Categories

Resources