Join clause incorrect on multiple join LINQ - c#

I have a multiple join query like this:
public static List<Answer> GetDetailedAnswers(string Tag)
{
using (Database db = new Database())
{
List<Answer> answer =
from quest in db.Question
join answ in db.Answer on quest.ID equals answ.QuestionID
join deal in db.Dealer on answ.DealerID equals deal.ID
join country in db.Country on deal.CountryID equals country.CountryID
where quest.ParentSection == Tag
select new
{
ParentSection = quest.ParentSection,
Section = quest.Section,
Dealer = deal.Name,
OriginalAnswer = answ.Original,
EngAnswer = answ.English,
Region = country.Country
}.ToList();
return answer;
}
}
And i have an internal class like this:
public class Answer
{
public string ParentSection { get; set; }
public string Section { get; set; }
public string Dealer { get; set; }
public string OriginalAnswer { get; set; }
public string EngAnswer { get; set; }
public string Region { get; set; }
}
I get an error on the last join. It says "the type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'"
What did i miss? Thx

For the error: "AnonymousType#1 does not contain a definition for 'ToList' and no extension method 'ToList'", You can do following.
public static List<Answer> GetDetailedAnswers(string Tag)
{
using (Database db = new Database())
{
List<Answer> answer =
(from quest in db.Question
join answ in db.Answer on quest.ID equals answ.QuestionID
join deal in db.Dealer on answ.DealerID equals deal.ID
join country in db.Country on deal.CountryID equals country.CountryID
where quest.ParentSection == Tag
select new Answer
{
ParentSection = quest.ParentSection,
Section = quest.Section,
Dealer = deal.Name,
OriginalAnswer = answ.Original,
EngAnswer = answ.English,
Region = country.Country
}).ToList();
return answer;
}
}
You need to surround you query within round brackets and then apply .ToList() method to it.

Please check the data type of
deal.CountryID and country.CountryID. this should be same

Related

EF Linq Query nested .ToList()

looks like I got stuck with a nested Linq Query. I have 4 Tables which I want to join. Basically a journal has one Recipient and multiple Readers. I'd like to show the Journal with it's Recipient and all it's Readers. Here's the EF Query
var myJournals = (
from s in db.Journals
where !s.Blacklist
join recToJournals in db.RecipientsToJournals on s.JournalID equals recToJournals.JournalID
join recipients in db.Recipients on recToJournals.RecipientID equals recipients.RecipientID
join reaToJournals in db.ReadersToJournals on s.JournalID equals reaToJournals.JournalID
join readers in db.Readers on reaToJournals.ReaderID equals readers.ReaderID
select new AnalysisViewModel
{
JournalID = s.JournalID,
Title = s.Title,
RecipientName = recipients.FullName,
ReaderList = readers.FullName.ToList()
});
return View(myJournals);
Here's the ViewModel:
public class AnalysisViewModel
{
public int JournalID { get; set; }
public string Title { get; set; }
public List<Char> ReaderList { get; set; }
public string ReaderName { get; set; }
public string RecipientName { get; set; }
}
Here I'll get an Exception System.NotSupportedException: The method 'ToList' is not supported when called on an instance of type 'String'.
If I use ReaderName = readers.FullName it works, but I get a List with multiple Journals and their Readers.
How can I show only one Journal with it's Recipient and all it's Readers?
This does not make sense. Why are you calling ToList on a string? Why would you even want List<char>? Change your model so the type is of string and remove ToString
Change 1 - in your linq statement
ReaderList = readers.FullName // remove .ToList
Change 2 - in your model
public string ReaderList { get; set; }
Although it is not technically wrong it is not best practice to name a property of type string (or any non collection type for that mater) with the suffix List. A more suitable name would be ReaderName.
First of all change your ViewModel
public class AnalysisViewModel
{
public int JournalID { get; set; }
public string Title { get; set; }
public string RecipientFullName { get; set; }
public List<string> ReadersFullNames { get; set; }
}
You need GroupBy
var myJournals = from s in db.Journals
where !s.Blacklist
join recToJournals in db.RecipientsToJournals
on s.JournalID equals recToJournals.JournalID
join recipients in db.Recipients
on recToJournals.RecipientID equals recipients.RecipientID
join reaToJournals in db.ReadersToJournals
on s.JournalID equals reaToJournals.JournalID
join readers in db.Readers
on reaToJournals.ReaderID equals readers.ReaderID
select new
{
JournalID = s.JournalID,
Title = s.Title,
RecipientFullName = recipients.FullName,
ReaderFullName = readers.FullName
};
var result = myJournals.GroupBy(j => new { j.JournalID, j.Title, j.RecipientFullName })
.Select(g => new AnalysisViewModel
{
JournalID = g.Key.JournalID,
Title = g.Key.Title,
RecipientFullName = g.Key.RecipientFullName,
ReadersFullNames = g.Select(r => r.ReaderFullName).ToList(),
}
)
.ToList();

how to write an EF query to join three tables and order by a field?

I have the following 3 tables structured in the way as shown below. I am trying to write an entity framework join query among the 3 tables
to
Select joblink, usersubmitted, runstatus, submitted_time, changelist
orderby submitted time
I was able to join and retrieve data from 2 tables but cant figure out
on how to join 3 tables, can anyone provide guidance on how to do this?
lookahead_run (Table#1)
+-------------------+--------+----------------+-------------------+----------+
lookahead_run_id(PK)|joblink | usersubmitted |submitted_time |runstatus
+-------------------+--------+----------------+-------------------+----------+
15963---------------+link1---+---username1----+2017-03-17 22:28:53--Fail-----
lookahead_run_change_list (Table#2)
+---------------+----------------+-----------------+
changelistid(PK)|lookahead_run_id|change_list_id
+---------------+----------------+-----------------+
38591-----------+15963-----------+34022
38590-----------+15963-----------+34021
38589-----------+15963-----------+34020
change_lists (Table#3)
+-------------+-----------+
change_list_id|changelist
+-------------+-----------+
34022-------- 1823900
34021-------- 1819483
34020-------- 1818572
UPDATED CODE;-
namespace Dashboard.Model.ApiModels
{
public class LookaheadRunInfo
{
public string ECJobLink { get; set; }
public List<String> gerrits { get; set; }
public string UserSubmitted { get; set; }
public string SubmittedTime { get; set; }
public string RunStatus { get; set; }
}
}
public IEnumerable<LookaheadRunInfo> GetLookaheadRunInfoSearch(LookaheadRunsFilterCriteria filterCriteria)
{
List<LookaheadRunInfo> lookaheadRunsInfo = new List<LookaheadRunInfo>();
var lookaheadRunData = bitDB.lookahead_run.OrderBy(x => x.lookahead_run_id).Skip(filterCriteria.PageNumber * filterCriteria.PageSize).Take(filterCriteria.PageSize).ToList();
foreach (var lookaheadRunRow in lookaheadRunData)
{
var lookaheadRunId = lookaheadRunRow.lookahead_run_id;
lookaheadRunsInfo = (from lrcl in bitDB.lookahead_run_change_list
join cl in bitDB.change_lists on lrcl.change_list_id equals cl.change_list_id
join lr in bitDB.lookahead_run on lrcl.lookahead_run_id equals lr.lookahead_run_id
where lrcl.lookahead_run_id == lookaheadRunId
orderby lr.submission_time
select new LookaheadRunInfo
{
lr.ec_job_link,
cl.change_requests,
lr.submitted_by,
lr.submission_time,
lr.lookahead_run_status,
}).ToList();
}
return lookaheadRunsInfo;
}
Error:-
Error 1 Cannot initialize type 'Dashboard.Model.ApiModels.LookaheadRunInfo' with a collection initializer because it does not implement 'System.Collections.IEnumerable'
You can put as many joins as you like in a query. if you want to select fields from multiple entities, you need to select a new object. I would suggest you to create a holder class to contain the joined contents, but i'm gonna show you how to do it with an anonymous type:
var lookaheadRunChangeListIds = (from lrcl in bitDB.lookahead_run_change_list
join cl in bitDB.change_lists on lrcl.change_list_id equals cl.change_list_id
join lr in bitDB.lookahead_run on lrcl.lookahead_run_id equals lr.lookahead_run_id
where lrcl.lookahead_run_id == lookaheadRunId
orderby lr.submitted_time
select new LookaheadRunInfo {
ECJobLink = lr.joblink,
UserSubmitted = lr.usersubmitted,
RunStatus = lr.runstatus,
SubmittedTime = lr.submitted_time,
gerrits = cl.changelist
}).ToList();
Note that the new { ... } can be replaced by a new NewClass { ... } where the NewClass contains all the selected fields.
Edit above: name your properties as you instanciate your LookAheadRun since the names are different, you should map them.

c# mvc apicontroller five table join and return value

can anyone please tell me, I have already joined five tables and I have tested join is correct. When I debug up to "Location1" values return.
Also I added return Location1, It says
"Error 1 Cannot implicitly convert type
'System.Collections.Generic.List' to
'System.Collections.Generic.IEnumerable'.
An explicit conversion exists (are you missing a cast?)"
My question is how can I display return valve?
This is my ApiController and class code.
public class Posts
{
public Suburb suburb { get; set; }
public SubRegion subRegion { get; set; }
public SubRegionDeliveryTime subRegionDeliveryTime { get; set; }
public DeliveryTime deliveryTime { get; set; }
public DeliveryPeriod deliveryPeriod { get; set; }
}
public IEnumerable<Posts> Get()
{
using (ApplicationDbContext db = new ApplicationDbContext())
{
var Location1 = (from su in db.TLCSuburb
join Subr in db.TLCSubRegion on
su.SubRegionID equals Subr.SubregionID
join srdt in db.TLCSubRegionDeliveryTime on
Subr.SubregionID equals srdt.SubregionID
join DT in db.TLCDeliveryTime on
srdt.DeliveryTimeId equals DT.DeliveryTimeId
join DP in db.TLCDeliveryPeriod on
DT.DeliveryPeriodID equals DP.DeliveryPeriodID
orderby Subr.SubregionID
select new
{
su.name,
su.postcode,
su.AuState,
su.Latitude,
su.Longitude,
DT.DeliveryDay,
DP.PeriodType,
Subr.CloseDayId,
Subr.SubregionName,
}).ToList();
//return null;
return Location1;
}
}
Write like this:
var Location1 = (from su in db.TLCSuburb
join Subr in db.TLCSubRegion on
su.SubRegionID equals Subr.SubregionID
join srdt in db.TLCSubRegionDeliveryTime on
Subr.SubregionID equals srdt.SubregionID
join DT in db.TLCDeliveryTime on
srdt.DeliveryTimeId equals DT.DeliveryTimeId
join DP in db.TLCDeliveryPeriod on
DT.DeliveryPeriodID equals DP.DeliveryPeriodID
orderby Subr.SubregionID
select new Post
{
suburb = new Suburb(){
Name = su.name,
PostCode = su.postcode,
AuState = su.AuState,
Latitude = su.Latitude,
Longitude = su.Longitude
},
deliveryTime = DT.DeliveryDay,
deliveryPeriod = new DeliveryPeriod(){
PeriodType = DP.PeriodType
},
subRegion = new SubRegion(){
CloseDayId = Subr.CloseDayId,
SubRegionName = Subr.SubregionName
}
}).ToList();
You'll have to explicitly convert it to IEnumerable<Post> instead of an anonymous type.

linq join return type [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
LINQ to SQL: Return anonymous type?
What return type do I use for a List<> on a linq join? I'm joining multiple tables below, I'm getting the error 'Cannot implicitly convert type System.Collections.Generic.List<AnonymousType#1> to System.Collections.Generic.List<CargoTanksDAL.aspnet_Users>
public List<> GetAspnetUsersWithMembershipAndCompany()
{
using (DevCargoEntities db = new DevCargoEntities())
{
var users = from u in db.aspnet_Users
join mem in db.aspnet_Membership on u.UserId equals mem.UserId
join cl in db.CT_CompanyLogIn on u.UserName equals cl.UserLogIn
join companies in db.CT_Companies on cl.CompanyID equals companies.CompanyID
select new
{
u.UserId,
u.UserName,
mem.Email,
mem.IsLockedOut,
mem.IsApproved,
mem.CreateDate,
companies.CompanyName
};
return users.ToList();
}
}
None. The join does not matter here, the select does, and you select an anonymous type. You can't return an anonymous type. Better create a new class that contains the properties you want to return and instanciate that type.
You could theoretically return dynamic or object, but that is a path you really really don't want to walk. Trust me on that.
I would have made a new class.. for this user..
public class SomeKindOfUser
{
public int UserId { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public bool IsLockedOut { get; set; }
public bool IsApproved { get; set; }
public DateTime CreateDate { get; set; }
public string CompanyName { get; set; }
}
Now you can use
public List<SomeKindOfUser> GetAspnetUsersWithMembershipAndCompany()
Then in the select :
select new SomeKindOfUser
{
UserId = u.UserId,
UserName = u.UserName,
Email = mem.Email,
IsLockedOut = mem.IsLockedOut,
IsApproved = mem.IsApproved,
CreateDate = mem.CreateDate,
CompanyName = companies.CompanyName
};

Get Linq Subquery into a User Defined Type

I have a linq query, which is further having a subquery, I want to store the result of that query into a user defined type, my query is
var val = (from emp in Employees
join dept in Departments
on emp.EmployeeID equals dept.EmployeeID
select new Hello
{
EmployeeID = emp.EmployeeID
Spaces = (from order in Orders
join space in SpaceTypes
on order.OrderSpaceTypeID equals space.OrderSpaceTypeID
where order.EmployeeID == emp.EmployeeID group new { order, space } by new { order.OrderSpaceTypeID, space.SpaceTypeCode } into g
select new
{
ID = g.Key.SpaceTypeID,
Code = g.Key.SpaceTypeCode,
Count = g.Count()
})
}).ToList();
Definition for my Hello class is
public class Hello
{
public IEnumerable<World> Spaces { get; set; }
public int PassengerTripID { get; set; }
}
Definition for my World class is
public class World
{
public int ID { get; set; }
public string Code { get; set; }
public int Count { get; set; }
}
You are creating anonymous object but you need to specify type name World
select new World
{
ID = g.Key.SpaceTypeID,
Code = g.Key.SpaceTypeCode,
Count = g.Count()
})

Categories