asp.net entity framework - Complicated Queries with join + Membership user - asp.net

I have 2 tables.
Users - have userID, userMainGroup and userMinorGroup
Tasks - TaskId, UserId
My goal is:
I have current CurrentuserId and i want to show him all the tasks that were created by users from the same MainGroup as he.
In SQL i would write:
Select *
From Tasks Left join Users on tasks.Id=users.id
Where users.MainGroup=CurrentuserMainGroup; (var)
How do i do it using entity framework?
I understood that to make a join i need to write something like:
var tasks = from t in db.tasks
from u in db.users
where t.Id=u.Id
select new {t.Id, t.name....}
but where do i put the condition Where on the MainGroup?

you can try like this
var data= (from con in db.tasks
let UserMainGroup = db.users.where(x=>x.id==con.id).FirstOrDefault()
where UserMainGroup.MainGroup=CurrentuserMainGroup
select new {
ID=con.id,
Name=con.name
}).ToList();
i think this will help you.......

It is recommended that you use navigation properties in stead of manually coded joins:
from t in db.Tasks
where t.User.MainGroup == currentuserMainGroup
select new {t.Id, t.name.... , t.User.Name, ... }

Related

How to async join tables in RavenDB

I need to do query from two raven db tables.
I found almoust perfect solution in documentation, only problem is im using async session and have no idea what is async equivalent.
var q = from order in dq
let company = session.Load<Company>(order.Company)
select new
{
order.Freight,
company.Name
};
The correct syntax is:
RavenQuery.Load<Company>(order.Company)
https://ravendb.net/docs/article-page/5.4/csharp/indexes/querying/projections#example-viii---projection-using-a-loaded-document

How to use Linq where condition to check if a list of strings contains any string

I have a LINQ query like this:
var data = from user in _context.Users
select new
{
UserId = user.Id,
Username = user.UserName,
RoleNames = (from userRole in _context.UserRoles
join role in _context.Roles on userRole.RoleId
equals role.Id
where userRole.UserId == user.Id
select role.Name).ToList()
};
if (!string.IsNullOrEmpty(searchText))
data = data.Where(x => x.Username.Contains(searchText) || x.RoleNames.Any(r => r.Contains(searchText)));
The result are something like this:
User Id | Username | RoleNames
1 | Matt | [User, Admin]
2 | Jennifer | [User]
3 | John | []
But the
x.RoleNames.Any(r => r.Contains(searchText))
is not working, it's causing InvalidOperationException: The LINQ expression '...' could not be translated.
I want to pass in a searchText to search for either "Username" and "RoleNames" columns.
E.g. if I pass in searchText = 'Jen' it will return User Id 2, and if I pass in searchText = 'user' it will return User Id 1 and 2.
Any help would be appreciated.
While theoretically it is possible to translate this condition to the SQL, your EF Core version do not supports that. Consider to make filter before defining custom projection:
var users = _context.Users.AsQueryable();
if (!string.IsNullOrEmpty(searchText))
users = users.Where(x => x.Username.Contains(searchText) || x.Roles.Any(r => r.Contains(searchText)));
var data =
from user in users
select new
{
UserId = user.Id,
Username = user.UserName,
RoleNames = (from userRole in _context.UserRoles
join role in _context.Roles on userRole.RoleId
equals role.Id
where userRole.UserId == user.Id
select role.Name).ToList()
};
This may not be the answer you want now but you'll probably look back on this and see it as the right answer later.
Your ORM (Probably Entity Framework) can't translate your Linq Expressions into a query. If your project will have a small database and you don't need your queries to perform well then, tweak your expression so that the ORM can generate a functioning, albeit sub-optimal, query.
If data will be a significant part of your project then switch to a light ORM like Dapper and learn the query language of your database. Write optimal, parameterised queries in that query language and yield the long term benefits.

get the values of a foreign key

Hi is there an easy way to get the values of a foreign key, without writing sql queries.
I generated the code with the help of my mssql database (ADO.NET).
Here's an example for clarification
order table:
id customer_fk
1 100
2 105
customer table:
id name
100 Walter
105 White
view:
#model ...order
...
#customer_fk
#customer_fk delivers eg. "100" instead of "Walter"
Not sure if you are required to use ADO.NET, but to accomplish what you want, without writing sql, you'll need to use some kind of ORM, such as EntityFramework.
You will need to write LINQ, which generates SQL and since EF will know about the relationship between the two tables, you will have access to the "name" property in the customer table.
Linq to SQL might be a good option, since you're using MS SQL. Just add the DataContext item to your project, and drag/drop the tables from your server. Then you should be able to write something like:
public ActionResult Order(int orderId)
{
using (MyDataContext context = new MyDataContext())
{
var loadOptions = new LoadOptions();
loadOptions.LoadWith<order>(o => o.customer);
context.LoadOptions = loadOptions;
var theOrder = context.orders.Where(order => order.id == orderId).FirstOrDefault();
return View(theOrder);
}
}
But if you're already using ADO.Net, maybe just write the query? It's not that difficult:
SELECT order.*, customer.name
FROM order INNER JOIN customer ON order.customer_fd = customer.id
If you're doing this in Entity Framework (or some other similar ORM), you can write a LINQ query that joins to your foreign key table:
var customerOrders =
from o in context.Orders
join c in context.Customers on o.customer_fk equals c.ID
select new { OrderID = o.ID, CustomerName = c.Name };

Left Outer Join in Entity Data Model asp.net

how to implement Left outer join in Linq to entity framework. DefaultIfEmpty function is not supported.
please provide an example.
This works in .NET 3.5. When you join without doing "from" in combination with the FirstorDefault function, it will give you the row you are looking for in the left joined table. If you want multiple rows, just use where() instead.. Hope this helps.
====
comments = from p in _db.Master
join t in _db.Details on p.DetailID equals t.DetailID into tg
select new
{
A = p.Column1,
//this next column is the one from the left joined table
B = tg.FirstOrDefault(t => t.DetailID == p.DetailID).Column2
};
Entity framework in .NET 3.5 doesn't offer left join in Linq queries. The way to get "joined records" is through navigation property between entities. Something like:
var query = from u in context.Users
select new
{
User = u,
Orders = u.Orders.Where(...) // Filtered left join but User and Order must be related
};

Loading users from an SQL query - the correct way

I have an SQL query that lists the uid of all users who have a certain role:
SELECT u.uid
FROM {users} as u, {users_roles} as ur
WHERE u.uid = ur.uid AND ur.rid = 10 ORDER BY u.uid DESC
I need to load them all in an array as objects for listing.
I asked a question previously that left me only with the answer that what I wanted to do would be easier done without Views - so I'm going use a template file instead.
Therefore this question.
I know how to do this, but apparently my method is worth -2
This is how I want to do it:
$research['sql'] = "SELECT u.uid FROM {users} as u, {users_roles} as ur WHERE u.uid = ur.uid AND ur.rid = 10 ORDER BY u.uid DESC";
$research['sql_result'] = db_query($alumni['sql']);
// Load user objects and store in array
while($user_array = db_fetch_array($research['sql_result'])) {
// Create user objets based on uid
$user_obj = user_load($user_array['uid']);
// Load profile
profile_load_profile($user_obj);
$research['users'][$user_obj->uid] = $user_obj;
}
Please help me with how I should do it.
Your basic approach looks fine by me, except that the call to profile_load_profile() is redundant:
The user_load() function will invoke hook_user with operation 'load', and the profile module implements hook_user and calls profile_load_profile() for the load operation itself, so by the time you call it explicitly, it has already been called implicitly and you can just drop it.

Resources