Entity Framework 4.1 - select Many to Many Association - asp.net

I use Entity Framwork 4.1 and MVC 3. My question is about Join tables in Entity Framework.
I created three tables
User - UserId, Username
Role - Role Id, Rolename
UserInRoles- UserId, RoleId
I pulled these tables to my edmx file,
Only two tables appear i.e. the User and Role with a Many to Many Association between two.
If I want to get a user's role from UserInRoles table, What is the approach?
I did something like
var result = (from ar in roles
from au in users
where au.UserName == username
select new {});
This is not working. Please help.

As you guessed, the Entity Framework does combine simple look up tables like that into the parent tables in an effort to help you out. You won't be able to access the look up table in your code, but it will do the heavy lifting and allow you to navigate through the tables like such.
var result = (from ar in roles
where ar.Users.UserName == username
select ar);
Or if you prefer lambdas (personal preference):
var result = context.roles.Where(x => x.Users.UserName == username);

They should be linked I suppose:
var result =
from au in users
where au.UserName == username
select au.Roles;
Not sure if it will give you an empty collection by default. The Roles collection may have to be manually fetched. (Possibly result.Fetch(), but I'm not too familiar with it.)
(Or do you wat access to the actual UserInRole items that are stored in the database?)

Entity framework automatically generates a many to many relationship in the model, when there is only a relationshiptable with one shared primarykey that are foreign keys to other tables.
You can either add another column to this table to add it to your model or generate another unique key for the relationship.
Read more about this here :
http://learnentityframework.com/LearnEntityFramework/tutorials/many-to-many-relationships-in-the-entity-data-model/

Related

Entity Framework hides n to n table

I have the following tables created using SQL Server management studio (I must not let EF create the DB because I need customized indexing along with something else).
Table A (AId)
Table B (BId)
Table AB(AId, BId)
There are foreign key constrains setup so A - B is a n-n relationship.
Now, when I import the model into EF, the relationship is displayed as * - * (which is correct), but Table AB is gone. This is not what I want! I want to have the ability to manually manage the relationship. How can I have EF show this table?
(the reason is the way EF manage relationship through strongly typed objects is counter performance - e.g. I want to manually create a B and link it to some As (I know the ID) without selecting those As and adding it in B's collection)
As Slauma stated it is possible to add a dummy field, but more importantly you can remove that dummy field and still have the link table.
Simple create the table AB, with an extra column called "Dummy" for example. Generate your model from this table. The table will now be included in the model.
Now got to the database and drop the "Dummy" column.
You can now either refresh the model from the database of simple delete the mapping for the "Dummy" column. You now have the link table in your EF model.
It's not possible to force EF to expose the link table as an entity when you create the model via database first - unless you change the schema in a way that EF does not consider the table as a pure many-to-many link table anymore, for example by adding a "dummy column" to the table. When you are using Code-First however, you can manually create an entity for the link table with two one-to-many relationships between A and AB and between B and AB.
I am not convinced by your argument why you want to do that...
I want to manually create a B and link it to some As (I know the ID)
without selecting those As and adding it in B's collection.
...because you don't need to load any entities from the database if you know the key values. You can use attached stub entities in order to create the relationships and write entries into the link table:
var newB = new B { As = new List<A>() };
foreach (var aId in someAIdCollection)
{
var existingA = new A { Id = aId };
context.As.Attach(existingA);
newB.As.Add(existingA);
}
context.Bs.Add(newB);
context.SaveChanges();
No database query is involved here and the resulting SQL commands are the same like inserting an AB link entity directly.

How Get RoleID in ASP.NET MVC

Is there any way to get RoleId without get directly from DB?, I know we can get role Names by:
string[] allRoles = System.Web.Security.Roles.GetAllRoles();
string[] allRolesForUser = System.Web.Security.Roles.GetRolesForUser(httpContext.User.Identity.Name);
But I need to access roleId.
Does any one have any idea about it?
No. The role provider have no knowledge about the data source. It can be a very slow web service or a super deluxe NoSQL database. The provider doesn't know that your db as a primary key.
Sure. The SqlMembershipProvider does. But having it exposing the key would likely lead to violations against Liskovs Substitution Principle.
The role name should be unique. So you should yourself be able to fetch it from the database. Or why can`t you simply use the role name directly instead of the db key?
You must add aspnet_Roles table to your model and use query (for example LINQ) to get roleId .You can change MembershipProvider but it need more work for doing it.
You can't. ASP.NET MVC doesn't allow to get RoleId with standard functon, you must get it from database with the help of role name.
I realize this is a few years old, but when i bumped into it I saw that noone actually answers completely answers the question ...so I thought I would post a full solution.
Soooo...
Simply put:
SELECT RoleId, RoleName FROM aspnet_Roles;
GO
But for getting RoleIds for a User it is like this:
SELECT UR.RoleID, R.RoleName FROM
aspnet_Users U, aspnet_Roles R, aspnet_UsersInRoles UR
WHERE U.UserName = #Username
AND UR.UserId = U.UserId
AND UR.RoleID = R.RoleId
GO
This will give you a 2 column list of RoleIds and RoleNames for a particular user.
In reality, you should not be trying to do this as there is a potential for Security breach when a RoleId is exposed. You should only work with RoleNames and use the Membership and Roles methods to manage things.
Hope this helps :)

Doctrine 2.1 - Map entity to multiple tables

I have the following database situation:
wp_users (user table generated by wordpress)
ID | user_login | ...
wp_sp_user (extension to the wp_users table)
ID (FK) | surname | address | ...
Now I've already been trying for hours to "fuse" those two tables into one single User entity, e.g:
class User {
var ID;
var user_login;
var surname;
var address;
...
}
Is there any way to accomplish such a mapping without modifying the wp_user table (which I don't want to do for updating reasons)?
Some times database refactoring is not possible or the table has his own "raison d'ĂȘtre". In this cases you can use inheritance. Your User class can extens Account. Map Account to wp_users and extend it with wp_sp_user table. User class will use columns of the two tables.
Here is the doctrine documentation:
https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/inheritance-mapping.html
This is not possible. It also doesn't make sense to do so.
You will need to physically merge the tables together in MySQL and create a Doctrine entity for that table. This is the only way you can ensure your data is clean and fully normalized.
Another possible solution is to create one entity for each table and use a business object to combine results from each. This is not a very nice solution at all, as you will have to handle constraints on the application layer, and you will double the amount of queries you launch.

View with Not exists join to be used in Entity Framework

I need to create a view in SQL Server and to use it in a GridView on my .aspx page.
The view is mapped in my application through Entity Framework.
Here's my example:
SELECT User.UserName, User.UserId
FROM User
WHERE NOT EXISTS (SELECT UsersInRoles.RoleId FROM UsersInRoles
WHERE UsersInRoles.UserId = User.UserId AND UsersInRoles.RoleId = 'AdminRole')
The relation between User and UsersInRoles table is one-to-many.
I need to be able to pass the AdminRole value in my ASP.NET application.
I cannot use parameters in a view (i.e. using #Role is not allowed).
Only views and tables can bind to a GridView so a stored procedure (where a parameter
could be an option) is not good here.
Is there a workaround to use a LEFT OUTER JOIN maybe instead of the NOT EXISTS?
This way, having a JOIN on the UsersInRoles table, I could map the fields from UsersInRoles through Entity Framework in my application and I could add conditions there (with EntityDataSource.Where clause).
For Exists, use the Any extension method in LINQ. For Not Exists, use !Any.
var query = from user in User
where !user.UsersInRoles.Any(role => role.RoleId == 'AdminRole')
select new {user.UserName, user.UserId};
I'm quite new in EF, but I know that we can use stored procedures (or functions) in it.
Try read this

Entity Framework - Use join table to return collections of Followers / Following

Using Entity Framework, I am writing a social networking app and trying to setup some relationships so that I can have Users with Followers/Following properties.
I have a Users table:
Users
_______
Id
FirstName
LastName
Email
Then I have a Follows table:
Follows
__________
FollowerId
FolloweeId
On a strongly typed User object, I want to see .Followers and .Following properties that return collections of User objects. So far I've tried making the columns in the Follows table as foreign keys, and both as composite primary keys. The entity model comes out the way I want it (I don't have an Entity in-between, and I just have to rename the navigation properties), but when I populate with data, the Followers and Following collections are empty, so something is not right with the relationships.
I suppose I could separate and have two tables, Followers and Following, but I would have duplicate data and would have to add to two tables when someone follows someone else.
You need to include the data for the tables you User tables has relationships with in your query.
A query like this:
using (EntityObject context = new EntityObject())
{
var user = from x in context.users.Include("Followers").Include("Followees") //use your tables
where x.Id == TheUserId
select x;
}
Will let you have access to the objects for those included tables.

Resources