Sub query in linq to sql - linq

I want to return the comma seperated of the sub query result in my sql command.
As follow:
Select [User].UserName,
(Select [Role].Name + ', '
From
Security.UserRole As UserRole
Inner Join
Security.[Role] As [Role]
On UserRole.RoleId = [Role].RoleId
Where UserRole.UserId = [User].UserId
For Xml Path('')
)
From Security.[User] As [User]
Basically each user has multiple roles, and I want to load the roles names in comma separated format for each user.
The result set in Sql is like :
Is there any way I can write this query in LINQ ?
Thanks

Try Code
Create a Method Get User roles Particular User
Public String GetuserRoles(int userid)
{
string strroles="";
(from UserRole in Security.UserRole
join Role in Security.Role on UserRole.RoleId equals Role.RoleId
where UserRole.UserId==userid
select new
{
strs = Role.Name + ","
}).ToList().ForEach(c => strroles = strroles + c.strs);
return strroles;
}
After Write Your Linq Query:
var result=( from p in Security.User select new {
UserName=p.UserName,
Roles=GetuserRoles(p.UserId)
}).ToList();

Related

hibernate - Dynamic sort in a query

I have a Dao method that returns list of "posts" and looks like this:
public List<PostDTO> getPosts() {
Session session = sessionFactory.getCurrentSession();
return postList = session
.createQuery("select new com.poster.app.dto.PostDTO(p.id, p.date, p.title, p.text, p.imageUrl, p.author, p.category, count(c.post.id)) "
+ "from Post as p left join Comment as c ON p.id = c.post.id group by p.id",
PostDTO.class).getResultList();
}
So it basically just creates query and returns the dto's in that case. The thing is, i need to fetch exact same list BUT with different sorting. like i need to sort it dynamically by "newest", "most popular" and by "comments number" and i want to do this in one method instead of creating 3 methods for each ("newest", "most popular" and by "comments number"), how can i do that in hibernate?
You have choice between :
Use api criteria to build your query and add dynamically your order by clause.
Add the order by clause at the end of your query depending on your param
ex with 2nd option:
public List<PostDTO> getPostsOrderBy(String orderParam)
{
Session session = sessionFactory.getCurrentSession();
String query = "select new com.poster.app.dto.PostDTO(p.id, p.date, p.title, p.text, p.imageUrl, p.author, p.category, count(c.post.id)) "
+ "from Post as p left join Comment as c ON p.id = c.post.id group by p.id order by "+ orderParam;
return postList = session.createQuery(query,PostDTO.class).getResultList();
}

Using AutoMapper for JOIN operation without Foreign key

I have db TABLES:
Company(CompanyId, Name, UserId, CompanyType, Uid)
User(UserId, FirstName, LastName, SocialNumber)
And in application MODEL:
CompanyModel(CompanyId, Name, CompanyType, Uid, UserName)
Since CompanyModel and Company have many same type and name Fields I tend to use AutoMapper to avoid writing explicitly all of those fields.
But here I now need to get UserName.
If UserId had FK I would have been able to do it like this:
var mapper = Mapper.CreateMap<Company,CompanyModel>();
mapper.ForMember(
d => d.UserName,
s => s.MapFrom(a => a.User.FirstName + " " + a.User.LastName));
var q = companyQuery.Project().To<CompanyModel>();
But UserId in Company table don't not have Foreign key relationship constrain with User and I can't create it.
So at the moment I am doing it with join:
var r =
from c in companyQuery
join u in userQuery on c.UserId equals u.UserId
select new CompanyModel
{
CompanyId = c.CompanyId,
Name = c.Name,
CompenyType = c.CompanyType,
Uid = c.Uid,
UserName = u.FirstName + " " + u.LastName
};
I would like to know if there is any way to do this with AutoMapper, and how? so I can skip naming all fields (this is just sample, there are much more fields).
Is anyone familiar with this ?

How to Execute a method inside LINQ to Entities'

var users = from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
I would like to select the roles from the database and create a list of UsersViewModel. However Entity Framework is trying to execute the projection on the SQL side, where there is no equivalent to Roles.GetRolesForUser.
What would be an alternative to this or how am I suppose to execute any method inside the query?
The easiest is to get the data you want from SQL, then after the query executes, iterate through the results and populate the additional details from the function in your code.
Example:
var users = (from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled
}).ToList();
foreach(var user in users){
user.Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault();
}
The key to remember here is to separate out what you're doing (understanding the separation of concerns in your architecture). Take care of the SQL first, then augment the data from other sources, in your case the Role Provider.
You can force the query to execute before creating the ViewModels by adding ToList():
var users = from u in db.UserProfiles.ToList()
select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
As CodeMonkey1313 noted, I strongly suggest you apply some sort of filter in your query:
var users = from u in db.UserProfiles
.Where( x => /* apply filter here */ )
.ToList() //Force query to execute
select new UsersViewModel {
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName).FirstOrDefault()
};
You can convert your Queryable to an Enumerable that executes locally:
var users = (from u in db.UserProfiles select new UsersViewModel{
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled)}
).AsEnumerable()
.Select(u => new {
UserName = u.UserName,
UserId = u.UserId,
IsDisabled = u.IsDisabled,
Role = Roles.GetRolesForUser(u.UserName) })
.FirstOrDefault()

showing multiple rows from database in datagridview using entity framework

I am trying to show multiple records from database in datagridview but I'm having only a single record all the time.
2 tables are involved in this query, from 1st table I acquire all the id's those fulfill the condition and from 2nd table I am getting the user information.
1st table is tblUsers_Roles and 2nd is tblUsers.
These tables have primary/foriegn key relationship.
Here is my code:
IEnumerable<tblUsers_Role> id = db.tblUsers_Role.Where(a => a.User_Role == selectRole);
foreach (var user in id)
{
var userinfo = from b in db.tblUsers
where b.User_Id == user.User_Id
select new { b.First_Name, b.Last_Name, b.Status, b.Authenticated };
dgvResults.DataSource = userinfo.ToList();
dgvResults.Show();
}
You are assigning the grid in the loop. That is not going to work. Maybe something like this will work:
var userinfo =(from ur in db.tblUsers_Role
join u in db.tblUsers
on ur.User_Id equals u.User_Id
where ur.User_Role == selectRole
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Or a alteretive would be like this:
var roles=db.tblUsers_Role
.Where(a => a.User_Role == selectRole)
.Select (a =>a.User_Id).ToList();
var userinfo=
(
from u in db.tblUsers
where roles.Contains(u.User_Id)
select new
{
u.First_Name,
u.Last_Name,
u.Status,
u.Authenticated
}
).ToList();
dgvResults.DataSource = userinfo;
dgvResults.Show();
Not as nice as the first one. But maybe you understand the concept.

Using LINQ to pull MembershipUser.Username into a new object

I have the following code and I need to pull out each user's username from the membership tables:
var results = (from u in db.U_USER
where u.Forename.ToLower().Contains(search)
|| u.Surname.ToLower().Contains(search)
select new ExUser
{
MembershipId = u.MembershipId,
Surname = u.Surname,
Forename = u.Forename,
Username = Membership.GetUser(u.MembershipId).UserName
});
Now I know why im getting the following, but can anybody recommend a solution?
LINQ to Entities does not recognize the method 'System.Web.Security.MembershipUser GetUser
LINQ to Entities is trying to translate your select expression into T-SQL, which it can't because there's no ExUser etc. in T-SQL.
Finhish off the expression with a call to AsEnumerable or similar, and then perform the projection:
var results = (from u in db.U_USER
where u.Forename.ToLower().Contains(search)
|| u.Surname.ToLower().Contains(search)
select u)
.AsEnumerable()
.Select(u => new ExUser
{
MembershipId = u.MembershipId,
Surname = u.Surname,
Forename = u.Forename,
Username = Membership.GetUser(u.MembershipId).UserName
});
You can do it by forcing the results into memory by using AsEnumerable. When the results are in memory you can call Membership.GetUser without linq attempting to translate it to sql:
var results = (from u in db.U_USER
where u.Forename.ToLower().Contains(search) || u.Surname.ToLower().Contains(search)
).AsEnumerable().Select(u => new ExUser {
MembershipId = u.MembershipId,
Surname = u.Surname,
Forename = u.Forename,
Username = Membership.GetUser(u.MembershipId).UserName
});

Resources