LINQ Type arguments cannot be inferred - c#

I have two objects that I want to join _locations and lrsLocations. I want to update _locations attributes with the corresponding lrsLocations. To do this I am using LINQ to get references to both options and then going through and updating ms2 attributes to be lrs (I know this isn't what LINQ was made for so I am open to new ideas. I am using this LINQ query now:
var joinResult =
from
ms2 in _locations
from
lrs in lrsLocations
where
ms2.LRS_ID == lrs.attributes.route_id
&&
ms2.LRS_LOC_PT == lrs.attributes.measure
select
new {ms2, lrs};
It works but I really need a LEFT OUTER JOIN so after some googling I attempting:
var joinResult = from ms2 in _locations
join lrs in lrsLocations on new { ms2.LRS_ID, ms2.LRS_LOC_PT }
equals new { lrs.attributes.route_id, lrs.attributes.measure } into merge
from lrs in merge.DefaultIfEmpty()
select new { ms2, lrs };
The issue is that the join lrs complains: http://i.imgur.com/5EAeFmx.png (Click for picture)
So I either need a way to convert my working LINQ to be a LEFT OUTER JOIN, or understand what the problem is talking about in the new one, because a google didn't give me much insight.

The anonymous types in your JOIN must have the same property names:
join lrs in lrsLocations on new { ms2.LRS_ID, ms2.LRS_LOC_PT }
equals new { LRS_ID = lrs.attributes.route_id, LRS_LOC_PT = lrs.attributes.measure }
Obviously the types have to match as well. If they don't you need a conversion or a cast.

Related

How do I group one to many in a nested fashion with linq to entities?

I have three tables, Chart, ChartQuestion, ChartAnswer
A Chart has many ChartQuestions, a ChartQuestion has many ChartAnswers.
I'd like to do a linq query that gives me an object containing all of this data, so it'd be a ChartObject containing List<ChartQuestion> and each ChartQuestion contains a List<ChartAnswer>
I started with this:
(from chart in db.Chart
join chartQuestion in db.chartQuestion on chart.ChartId equals chartQuestion.ChartId into chartQuestions)
This seems to be the first step. However I want to include the ChartAnswers now, so I have to do another join to pull back the ChartAnswers but I don't know how to do this.
I can't do a join, and while I can do a from, I am not sure of the exact syntax.
(from chart in db.Chart
join chartQuestion in db.chartQuestion on chart.ChartId equals chartQuestion.ChartId into chartQuestions
from chartQuestionsSelection in chartQuestions
join chartAnswer in context.ChartAnswers on chartQuestions.ChartAnswerId equals chartAnswer.ChartAnswerId into chartAnswers // This is wrong
)
With that code above you end up as chartAnswers being separate to the chartQuestions rather than belonging to them, so I don't think it is correct.
Any idea?
joining a table destructors it i.e. you now have the row as a variable if you need it in a nested fashion then select in like this
(from chart in db.Chart
select new { //can also be your own class/record, perhaps a DTO
chart.Id,
chart.Name,
questions = (from chartQuestion in db.chartQuestion
where chart.ChartId == chartQuestion.ChartId
select new { //perhaps a dto
chartQuestion.Id,
chartQuestion.Question,
Answers =
(from chartAnswer in context.ChartAnswers
where chartAnswer.ChartAnswerId == chartQuestion.ChartAnswerId
select chartAnswer).ToList() //this is translated and not evaluated
}).ToList() //this is translated not evaluated
}).ToListAsync(cancellationToken) //this will evaluate the expression
If you need it by joins then you can group join it like this:
from m in _context.Chart
join d in _context.ChartQuestions
on m.ID equals d.ID into mdJoin
select new
{
chartId = m.ID,
chartName = "m.name",
quess = from d in mdJoin
join dd in _context.ChartAnswer
on d.Iddomain equals dd.DomainId into anJoin
select new
{
quesId = d.ID,
quesName = d.Question,
anss = anJoin
}
}
A better way: If you edit your DbConfigurations to include navigation properties of each then the code will become way simpler.
example:
db.Chart
.Include(x => x.chartQuestions)
.ThenInclude(x => x.chartAnswers)
You can search more about how to do navigation properties in EFCore, but ofcourse if the code base is large then this might not be feasible for you.
Try following :
(from chart in db.Chart
join chartQuestion in db.chartQuestion on chart.ChartId equals chartQuestion.ChartId
join chartAnswer in context.ChartAnswers on chartAnswer.ChartAnswerId equals chartQuestion.ChartAnswerId
)

Linq Join Error: The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'

This is the code i've tried to join two collections its not working please help
var query = from p in collection.AsQueryable()
join o in collection1
on p.tag_description equals o.key into joined
from sub_o in joined.DefaultIfEmpty()
select new { p.tag_id, sub_o.record_hour };
It seems that you have two different datatype's variable in On Clause.
You need to make it same. This is the sample code for that
on new { Description= p.tag_description } equals new { Description= (string)o.key }

EF - anonymous type cannot have multiples... [duplicate]

This question already has answers here:
An anonymous type cannot have multiple properties with the same name
(2 answers)
Closed 6 years ago.
I have a method with which is the following:
using (ubmmsEntities db = new ubmmsEntities())
{
var result = (from l in db.log_documents
join t in db.teams on l.op_user_team equals t.id
where l.tracking_id == trackingID
select new { l.op_code, l.op_date, l.op_description, l.op_refer_code, l.op_refer_comments, t.team_name, l.id });
return result.
Now I have to add another column it, and in simple SQL all I would need is to add two more inner joins, but I am quite lost how to do it in EF a the below results a error under t2.team_name "An anonymous type cannot have multiple properties with the same name".
using (ubmmsEntities db = new ubmmsEntities())
{
var result = (from l in db.log_documents
join t in db.teams on l.op_user_team equals t.id
join r in db.refers_codes on l.op_refer_code equals r.code
join t2 in db.teams on r.id equals t2.id
where l.tracking_id == trackingID
select new { l.op_code, l.op_date, l.op_description, l.op_refer_code, l.op_refer_comments, t.team_name, l.id, t2.team_name });
return result.ToList();
}
So, I looked over here and there, and found this thread, but I am unable to figure out how to apply the solution to my method. I googled for "EF naming types" and similar to try to understand what is being asked from me, but honestly I was unable to figure out by myself.
So, I believe the problem is because EF wants me to set a unique name to my db.team... which I thought I'd given it by calling it t2. This approach does work on SQL, but I do not understand how to apply the same to my method. I did find some clues such as new{t2=t.id} but different errors starting to pop-up in different places.
Help/Directions please?
You can give names to properties in your projectction ie
.Select(x => new { firstItem = x.y, secondItem = x.x });
You can use this to get around your problem.
Or, as you are doing it:
select new { firstItem = x.y, secondItem = x.x } .....

Switch gears from TSQL to LINQ

I am trying to take the TSQL below and convert it into LINQ. I'm obviously not very good at this and not sure how to go about doing a join in Linq. My confusion goes a little beyond just the simple expression. In my basic uses my result set is a class that of course represents a table row...but a join would not have this one to one ratio so do I have to create a custom result set?
TSQL:
SELECT
SimEA.*,
SimE.*
FROM
dbo.SSimEmailsAdressees SimEA
JOIN dbo.SSimEmails SimE ON
SimEA.EmailID = SimE.EmailMsgID
WHERE
SimEA.UserId = var
The closest I have come:
this.GetAll<SSimEmails>()
.Where(e => e.SSimEmailsAdressees.Any(p => p.UserId.ToString() == usrID));
Which of course return an object that is a mimic of the single table being queried. So I need help getting the join added and I'm guessing I'll have to create a return object something like this?
this.GetAll<MyJoinResultsObject>......
I think that you should write something like:
var q =
from SimEA in SSimEmailsAdressees
where SimEA.UserId = usrID
join SimE in SSimEmails on SimEA.EmailID equals SimE.EmailMsgID
into joinSimE
from SimE in joinSimE.DefaultIfEmpty()
select new { EmailID = SimEA.EMailID, UserId = SimEA.UserId, OtherField = SimE.OtherField };
var result = from ea in SimEA
join e in SimE
on ea.EmailID equals e.EmailMsgID
where ea.UserId = userId
select new { properties you want here or new object based on properties}

LINQ: Left Outer Join with multiple conditions

I have two IEnumerables called BaseReportDefinitions and InputReportDefinitions. I need to do a left outer join where i want all the InputReportDefinitions and whichever BaseReportDefinitions that match. Both IEnumberables contain ReportDefinition objects that contain ParentName and ReportName properties that need to be used as the join key. I want to return the ReportDefinition object for each (in the case of BaseReportDefinition entry it may be null) in an anonymous object.
I have seen many examples of linq outer joins and outer joins with a static second condition that often gets put into a where condition but nothing that really uses two conditions fully for the join.
var items = inputReportDefinitions.GroupJoin(
baseReportDefinitions,
firstSelector => new {
firstSelector.ParentName, firstSelector.ReportName
},
secondSelector => new {
secondSelector.ParentName, secondSelector.ReportName
},
(inputReport, baseCollection) => new {inputReport, baseCollection})
.SelectMany(grp => grp.baseCollection.DefaultIfEmpty(),
(col, baseReport) => new
{
Base = baseReport,
Input = col.inputReport
});
I believe this ends up being a left outer join. I don't know how to convert this monstrosity to a query statement. I think if you add AsQueryable() to the end it could be used in Linq-to-SQL, but honestly, I have little experience with that.
EDIT: I figured it out. Much easier to read:
var otherItems = from i in inputReportDefinitions
join b in baseReportDefinitions
on new {i.ParentName, i.ReportName}
equals new {b.ParentName, b.ReportName} into other
from baseReport in other.DefaultIfEmpty()
select new
{
Input = i,
Base = baseReport
};

Categories