I have two tables
I am trying to write a LINQ Query where I want to select everything in Table 1 but instead of CaseStatusID, I want to return the actual status (Corresponding to CaseStatusID in Table 2).
I have the query but I the error Cannot convert expression type 'System.Collections.Generic.List<CaseId:int, Status:string>' to return type 'System.Collections.Generic.List<Data.Cases>'
I have not been able to find a good example to help me. How can I achieve this?
public List<Case> GetAllCases()
{
var result = (from c in _Context.Cases
join s in _Context.CaseStatus on c.CaseStatusId
equals s.CaseStatusId
select new { c.CaseId, c.CaseStatu.Status }).ToList();
return result;
}
Your return type doesn't match the declared return type List<Case>. When you select new {}, you are actually returning an anonymous object from your linq expression. You can fix it like this:
public List<Case> GetAllCases()
{
var result = (from c in _Context.Cases
join s in _Context.CaseStatus on c.CaseStatusId
equals s.CaseStatusId
select new Case { CaseId = c.CaseId, CaseStatus = c.CaseStatu.Status }).ToList();
return result;
}
Note the new Case{} when selecting your data. You may need to change CaseId and CaseStatus properties to match the actual properties from the Case class.
Update: To Clarify, you would need a Case class that looked minimally like this:
public class Case {
public int CaseId { get; set; }
public string CaseStatus { get; set; }
}
I think the problem is in the select statement where you should return objects list of Case:
public List<Case> GetAllCases()
{
var result = (from c in _Context.Cases
join s in _Context.CaseStatus on c.CaseStatusId
equals s.CaseStatusId
select new Case () { CaseId = c.CaseId, CaseStatusId = c.CaseStatusId }).ToList();
return result;
}
you are creating list of annonymous type and returning list of case. that is the issue
Related
Hi Have a two tables that have a relationship like below ..
class Boothtable
{
public int BoothId {get;set;}
public string BoothName {get;set;}
public double Price {get;set;}
public int RoomId{get;set;}
}
class RoomTable
{
public int RoomId {get;set;}
public string RoomName{get;set;}
public sting Location {get;set;}
}
I am trying to write a join query using LINQ to join the the boothtable to the roomstable on RoomId and return all properties from the boothtable and only return the RoomName property from the Rooms table. is there anyone that can direct me how to achieve this?
So far i have a linq exp like this but it only returns all properties from the booths table.
var getData = from boothtable in context.Boothtable
join roomtable in context.RoomTable
on boothtable.RoomId equals roomtable.RoomId
where boothtable.BoothId == someId
select boothtable;
If you want to retrieve properties from both you must project an object containing data from both. This uses an anonymous object to do so:
select new { boothtable, roomtable }
If you want to return this collection of anonymous objects from a method then define a custom object with the two properties and instantiate it
select new YourCustomObjet { Booth = boothtable, Room = roomtable }
If you only want some of the properties (missed it at first) then as you project the objects in the examples above just project the specific fields:
select new
{
boothtable.BoothId,
boothtable.BoothName,
boothtable.Price,
roomtable.RoomName
}
Notice that if it is an anonymous object and the desired property names are the same, no need to explicitly define a name
Try this -
var getData = (from boothtable in context.Boothtable
join roomtable in context.RoomTable
on boothtable.RoomId equals roomtable.RoomId
where boothtable.BoothId == someId
select new
{
BoothId = boothtable.BoothId,
BoothName = boothtable.BoothName,
Price = boothtable.Price,
RoomName = roomtable.RoomName
});
I'm trying to select some data from a table in my database using a join in a linq query, but I can't seem to grasp how to save it to the list of DTO's that I would like to return.
I've been looking at this post for directions at using the lambda expression: C# Joins/Where with Linq and Lambda but it seems like that guy is trying to accomplish something slightly different than me; I want to compare the value CPR (from the table Coworkers) and the value CPR (From the table Duties) and select all of those where the Projektname (from the table Duties) are equal to the string projektname.
What I've written so far of the method is this:
public List<CoworkerDTO> GetCoworkers(string projektname)
{
_coworkerlist = new List<CoworkerDTO>();
using (var context = new F17ST2ITS2201608275Entities())
{
var dataset =
from co in context.Coworkers
join du in context.Duties on co.CPR equals du.CPR
where du.Projektname == projektname
select new {Coworkers = co};
foreach (var element in dataset.ToList())
{
_coworkerlist.Add(element);
}
}
return _coworkerlist;
}
The CoworkerDTO looks like this:
class CoWorkerDTO
{
public string Fornavn { get; set; }
public string Efternavn { get; set; }
public int Alder { get; set; }
public string CPR { get; set; }
public decimal AntalTimer { get; set; }
}
The table Coworkers has a column that corresponds to each of the properties above, so I guess my question is how to somehow convert the selection that I get into a list of the CoworkerDTOs.
Sorry for the long post, and if my english is a bit confusing, as it's not my first language.
Thanks in advance :)
You should convert Coworkers entity into CoWorkerDTO. You can do it manually (assume properties have same names and types):
var dtos =
from co in context.Coworkers
join du in context.Duties on co.CPR equals du.CPR
where du.Projektname == projektname
select new CoWorkerDTO {
Fornavn = co.Fornavn,
Efternavn = co.Efternavn,
Alder = co.Alder,
CPR = co.CPR,
AntalTimer = co.AntalTimer
};
return dtos.ToList();
Or you can use something like AutoMapper Queryable Extensions to do that projection automatically:
Mapper.Initialize(cfg =>
cfg.CreateMap<Coworkers, CoWorkerDTO>());
And query with projection will look like
var entities =
from co in context.Coworkers
join du in context.Duties on co.CPR equals du.CPR
where du.Projektname == projektname
select co;
return entities.ProjectTo<CoWorkerDTO>().ToList();
I am running a query to populate options in a single select drop down menu. When I debug the function below, the query variable contains the resultset that I am expecting. However when I skip next to where it should be returned to, I get the error:
'The entity type or complex type 'Models.zz_Member' cannot be constructed in a LINQ to Entities query."
public IQueryable<zz_Member> GetMembers(string searchText)
{
var _db = new Portal.Models.AuthorizationContext();
IQueryable<zz_Member> query = _db.zz_Members;
return query //.Where(a => a.memLastName.Contains(searchText))
.Select(a => new zz_Member()
{
ID = a.ID,
memFirstName = a.memFirstName,
memLastName = a.memLastName
}
);
}
The zz_Member model object is defined as:
public class zz_Member
{
[ScaffoldColumn(false)]
public int ID { get; set; }
public string memFirstName { get; set; }
public string memLastName { get; set; }
}
The error is thrown when I try to convert to an IList, but when I check the value of memList using the debugger, it shows the error text in the results view.
IQueryable<zz_Member> memList = GetMembers(e.Text);
IList<zz_Member> memList2 = memList.ToList();
I have also tried writing the GetMembers functions to return the list as so:
public IList<zz_Member> GetMembers(string searchText)
{
var _db = new WWCPortal.Models.AuthorizationContext();
return (from m in _db.zz_Members
where m.memLastName.Contains(searchText)
select new zz_Member { ID = m.ID, memFirstName = m.memFirstName, memLastName = m.memLastName }).ToList();
}
Any hints or answers to why the resultset appears to not be getting returned to the caller and put into memList? Thanks.
You cannot use framework dependant/generated entities in projection (with select new), hence the error.
Looks like you are trying to select specific columns instead of all columns, your options are
Project to a new class with those specific members
return all fields/columns for your entities like:
Code:
return query.Where(a => a.memLastName.Contains(searchText)); //without `select new`
I want to put the following code in a class by itself so that I can reuse it:
var activePersons = (from p in _dataContextOrders.Persons
select new
{
p.ID,
p.WindowsUserID,
p.Name,
p.CommonShortName,
p.TeamID,
p.Telephone,
p.Fax,
p.Email,
p.FMSBudgetOfficerID,
p.Active
}).Where(p => p.Active).OrderBy(p => p.CommonShortName);
So I can return the Object activePersons. I would replace all this with this:
var activePersons = DataAccessLayer.ActivePersons.GetActivePersons();
But further down the page, I have this:
var currentUser = activePersons.SingleOrDefault(p => p.WindowsUserID == strWindowsSessionUserId);
This now returns a compile error. Is there a way round this?
The reason you are getting the error is because of the anonymous object you are selecting in your query with new keyword. You can't return anonymous object from your method , so I guess you are returning object. Now for your method caller it is an object type object and it doesn't exposes all the properties selected in the query, (and you can't cast it to a type since you don't know the type) Hence the error.
You need to create a new class and with all the properties and return IEnumerable<yourClass> from the method.
There is a way to return anonymous object mentioned by Jon Skeet but he doesn't recommend it.
Define a class like:
class ReturnedObject
{
public int ID { get; set; }
public string WindowsUserID { get; set; }
//..... rest of the properties
}
and then in your query:
var activePersons = (from p in _dataContextOrders.Persons
select new ReturnedObject
{
ID = p.ID,
WindowsUserID = p.WindowsUserID,
//rest of the properties
in your method specify return type as:
public IEnumerable<ReturnedObject> GetActivePersons(//parameters
I'm using ActiveRecord on Subsonic 3 and I effectively want to do this:
select * from foo
left outer join bar on bar.Id = foo.barId
where foo.someProperty = 2
I've written a stored procedure to fetch the data but Subsonic has only created objects to hold the columns from foo and bar.
What's the best way of returning the data into a single object so I can just bind it. Ideally I want it to be in a list<> but without writing my own class, there doesn't seem to be a way provided by subsonic.
You have a couple options here...
You could create a database view that does your join, and have SubSonic generate a data type for your view, then your select would be just like selecting from any other table.
Alternatively, you could use a Linq expression to do the join into an anonymous or dynamic type (if you are using .net 4) For example:
public List<dynamic> LoadData(int id)
{
var data = from f in db.Foo
from b in db.Bar.Where(x => x.Id == f.BarId).DefaultIfEmpty()
where f.SomeProperty == id
select new
{
SomeProperty = f.Something,
AnotherProperty = b.SomethingElse
};
return data.Cast<dynamic>().ToList();
}
Of course another alternative is to do the Linq expression above, but define your own class to hold the returned data, and select into it.
public class MyData
{
public string SomeProperty { get; set; }
public string AnotherProperty { get; set; }
}
public List<MyData> LoadData(int id)
{
var data = from f in db.Foo
from b in db.Bar.Where(x => x.Id == f.BarId).DefaultIfEmpty()
where f.SomeProperty == id
select new MyData()
{
SomeProperty = f.Something,
AnotherProperty = b.SomethingElse
};
return data.ToList();
}