I have 2 tables in a database, and one class in C# (Letter).
Tables: tblUser(Id, Name), tblLetter(Id, UserId, Title)
Letter: (Id, Title, UserName)
I want select data with linq, and use this code:
List<Letter> lst = new List<Letter>();
lst = (from l in l.tblLetter.ToList()
select new {l.Id, l.Title, UserName = l.tblUser.Name}
).ToList();
and:
List<Letter> lst = new List<Letter>
(from l in l.tblLetter.ToList()
select new {l.Id, l.Title, UserName = l.tblUser.Name});
but get this error:
Cannot implicitly convert type...
As #SnowYetis comments, you are actually selecting an instance of a new, anonymous type in your code. That's what the syntax new { ... } does. Notice that there's no type name after the new directive.
If your Letter type has the properties Id, Title, UserName then all you need to do is change new { ... } to new Letter { ... }.
If not, then we probably need more information than you're giving us—for example, the definition of the Letter type.
There are a few issues in your code:
l.tblLetter.ToList() returns all records from your table. You typically don't call ToList() until the end of your query, to get just the data you need and no more.
You want to do a join between the two tables to get the matching user name.
If you want to return a collection of Letter, you can create instances of that in your select statement instead of creating an anonymous type.
Try this:
var lst = (from l in l.tblLetter
join u in tblUser on l.UserId equals u.Id
select new Letter
{
Id = l.Id,
Title = l.Title,
UserName = u.Name
}).ToList();
Related
Context
I am trying to get a list from select new:
var portfolioresult =
(from port in _context.Portfolio
join u in _context.Universe on port.CUSIP equals u.ID_CUSIP
join m in _context.MarketDataEvent on u.ID_CUSIP equals m.CUSIP_NUMBER_REALTIME
//select new { m, port.Name }).ToList();
select new ViewResult() { MarketDataEvents = m, PortfolioName = port.Name })
.ToList();
I want to get MarketDataEvents as List<MarketDataEvent>
Corresponding SQL query
SELECT me.*, p.Name FROM MarketDataEvent me
INNER JOIN universe u ON u.ID_CUSIP=me.CUSIP_NUMBER_REALTIME
INNER JOIN portfolio p ON p.CUSIp=me.CUSIP_NUMBER_REALTIME
Problem
I am not able to get a List inside select new. Is it possible to get something like this?
select new ViewResult() { MarketDataEvents = List<MarketDataEvents>, PortfolioName = port.Name })
Expected result
List<MarketDataEvents> "XYZ"
List<MarketDataEvents> "ABC"
Actual result
MarketDataEvent "XYZ
MarketDataEvent "XYZ"
MarketDataEvent "ABC"
Yes, it is possible:
var query =
from port in _context.Portfolio
select new ViewResult
{
MarketDataEvents =
(from u in _context.Universe.Where(u => port.CUSIP == u.ID_CUSIP)
join m in _context.MarketDataEvent on u.ID_CUSIP equals m.CUSIP_NUMBER_REALTIME
select m).ToList(),
PortfolioName = port.Name
};
var portfolioresult = query.ToList();
Essentially your m reference is out of scope. The input available to a select statement is only a single value out of the set available as a result of the select/joins you're looking at, which is why you don't see a list of all available from m, only a single value in each record.
Rather, you need to use a SelectMany since it'll expose an IEnumerable as the input to the function and you can split out the individual XYZ values out of that.
Attempting to display a table with a join on the Rating
to the ID within the Ratings table. I'm hitting an issue with the join within my statement.
var Movie = from u in _context.Movie
join g in _context.Ratings
on u.Rating equals g.ID
select (a => new List
{
Ratings = u.Rating,
MovieRating = g.MovieRating
});
Movie = await Movie.ToListAsync();
The type of one of the expressions in the join clause is incorrect. Type inference failed in the call to 'Join'.
You have some weird syntax like (a => new List { ... Not sure where you are going with that.
Do you have a class named List? are you trying to get a List? Why is "a" in there...since it is not referenced anywhere. You also try to change the type of the Movie variable in your code, the var keyword doesn't work that way. On the first line, you assign a IQueryable< T> to it and later on you try to assign a List< T> to it.
try something like this:
var movieQuery = from u in _context.Movie
join g in _context.Ratings on u.Rating equals g.ID
select new
{
Ratings = u.Rating,
MovieRating = g.MovieRating
};
var movies = await movieQuery.ToListAsync(); // query will be executed here
The example code above uses an anonymous class as result so movies will be of type List< T> where T is an anonymous class, if you do have a class called List (for some reason) representing a single result item, then use
select new List { ...
instead of
select new { ...
and if you don't wanna split the query / actual list into 2 variables, you can do something like:
var movies = await (from u in _context.Movie
join g in _context.Ratings on u.Rating equals g.ID
select new
{
Ratings = u.Rating,
MovieRating = g.MovieRating
}).ToListAsync();
I have two tables. Customer and CustomerBenefits.
Fields in each table
Customer - ID, Name, Address, Country etc
CUstomerBenefits - CustomerID, BenefitID (Both IDs have a relation to their relevant tables)
I am trying to list the customers and get the Benefit Details
IEnumerable<CustomerBenefit> GetData = from c in MyContext.CUstomerBenefits
where c.CustomerId == UserId & c.Active = true
orderby c.CustomerBenefit.BenType descending
select new {???? };
For the Select, Ive tried
select new {c.Benefit.Name }
but get the error
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Collections.Generic.IEnumerable'. An explicit conversion exists (are you missing a cast?)
If i change IEnumerable<CustomerBenefit> to IEnumerable<dynamic> i get no errors but when the data is bound to my gridview i get the error that a field is not found.
How could i keep IEnumerable<CustomerBenefit> and select the columns i require?
You wrote:
CUstomerBenefits - CustomerID, BenefitID (Both IDs have a relation to
their relevant tables)
I interpret this as meaning that there is a table CustomerBenefit that contains, well, benefits and that the CUstomerBenefits table in turn is a link between the customer and the benefits. And now you want to get a list of all the benefits that a specific customer has?
This should do the trick:
IEnumerable<CustomerBenefit> GetData =
from c in MyContext.CUstomerBenefits
where c.CustomerId == UserId && c.Active == true
orderby c.CustomerBenefit.BenType descending
select c.CustomerBenefit;
Use: select c to get all of the column values or:
select new CustomerBenefit {CustomerID = c.CustomerID}; etc
var HOQuotePremiums = (from holoc in objRes.ResHO.HOLocations
from cst in ((HOLocation)holoc).HOBuildings
select new
{
RequestId = cst.HOPremium.RequestId,
BasePremium = Convert.ToInt32(cst.HOPremium.BasePremium),
PersonalLiabilityPremium = cst.HOPremium.PersonalLiabilityPremium,
MedicalPaymentPremium = cst.HOPremium.MedicalPaymentPremium,
FinalPremium = objRes.ResHO.FinalPremium,
WithoutAOPDeductibleFinalPremium = cst.HOPremium.WithoutAOPDeductibleFinalPremium,
SubTotalPremium = objRes.ResHO.FinalPremiumWithoutFeeTax,
LocationID = holoc.LocationID,
BuildingID = cst.BuildingID,
IsMinimumPremium = cst.HOPremium.IsMinimumPremium,
MinimumPremium = cst.HOPremium.MinimumPremium,
SubTotalPremiumWithoutMinimumPremium = cst.HOPremium.SubTotalPremiumWithoutMinimumPremium,
FinalRate=cst.HOPremium.FinalRate,
}).ToList();
Please try this .
I'm a bit new to linq and I'm unsure if what I desire is possible. I basically have a class called User that contains a bunch of attributes. I want to only fill in the Name and ID fields that I'm getting from a query. My query gives me the appropriate results, but I am unsure of how to get it into user. This is the closest I get, but I realize it's incorrect.
IEnumerable<User> UserList;
UserList = (from o in dbContext.application_user
join p in dbContext.project on application_user.user_id = project.project_manager
select o);
This returns a list of User_ID, Firstname, and Lastname, but it doesn't fit into user. My user class has multiple variables, so I was thinking of approaching it by calling 3 IEnumerables, of types int, string, and string, if I could somehow fill all 3 from one query, and then set User = new User(name = x, id = x) etc. Such as
FNameList, LNameList, ID = *insert query here*
You can construct the User object inside the Linq query:
IEnumerable<User> UserList;
UserList = (from o in dbContext.application_user
join p in dbContext.project on application_user.user_id = project.project_manager
select new User(o.FName, o.LName, o.ID));
This assumes that User has a constructor taking three arguments like those, and that the properties on o are FName, LName, and ID, but you get the idea. The select clause can be used to transform the results into whatever format you need.
You can just create your instances of User with an Select transformation.
var userQuery = from o in dbContext.application_user
join p in dbContext.project on application_user.user_id = project.project_manager
select o;
IEnumerable<User> UserList = from o in userQuery.ToList()
select new User() {Name = o.Lastname, ID = o.user_ID};
I don't know how your User class looks like, but you get the idea.
I'm new to linq and I'm trying to databind to an anonymous type.
I'm using SubSonic 3.0 as my DAL.
I'm doing a select from 2 tables like so
var myDeal = (from u in db.Users
select new
{
UserID = u.UserID,
UserRoleID = (from ur in u.UserRoles where u.UserRoleID == ur.UserRoleID select ur).FirstOrDefault().UserRoleID
});
foreach (var v in myDeal) //dies first time here
{
}
Then when I databind or try to iterate through the collection I get the "Argument types do not match" error during run time.
I'm not sure what is going on here.
Is one of the ID fields nullable?
If so, you need to access the .Value property
var myDeal = (from u in db.Users
join ur in
select new
{
UserID = u.UserID,
UserRoleID = (from ur in u.UserRoles where u.UserRoleID.Value equals ur.UserRoleID select ur).FirstOrDefault().UserRoleID
});
You could also try something like this:
var myDeal = (from u in db.Users
join ur in db.UserRoles
on new {ID = u.UserRoleID.value} equals new {ID = ur.UserRoleID} into tempRoles
from roles in tempRoles.DefaultIfEmpty()
select new
{
UserID = u.UserID,
UserRoleID = roles.UserRoleID
});
You use tempRoles to execute a left outer join. So if there is no role assigned, you still get the userID.
I haven't tested this, this is just off the top of my head.
Good Luck,
Patrick.
"Argument types do not match" error is usually caused by the un-matching type between the property we would like to bind and its element.
Example in RadGridSparkline, when we would like to bind its item source
"Value" type must be double.
If we have the Value property defines as below
public decimal ContractValue
{ set; get; }
This error will be displayed