Entity Framework code first aspnet_Users mapping / joins - entity-framework

I was wondering with Entity Framework 4.1 code first how do you guys handle queries that involve an existing aspnet_Users table?
Basically I have a requirement for a query that involves the aspnet_Users so that I can return the username:
SELECT t.Prop1, u.Username
FROM Table1 t
INNER JOIN aspnet_User u ON t.UserId = u.UserId
Where t.Prop2 = true
Ideally in linq I would like:
from t in context.Table1
join u in context.aspnet_Users on t.UserId equals u.UserId
where t.Prop2 = true
But I'm not sure how to get aspnet_Users mapping to a class User? how do I make aspnet_Users part of my dbset ?
Any help would be appreciated, thanks in advance

Don't map aspnet_Users table or any other table related to aspnet. These tables have their own data access and their own logic for accessing. Mapping these tables will introduce code duplication, possible problems and breaks separation of concerns. If you need users for queries, create view with only needed information like id, user name, email and map the view. The point is that view will be read only, it will contain only allowed data and your application will not accidentally modify these data without using ASP.NET API.

First read Ladislav's answer. If you still want to go ahead : to do what you want would involve mapping the users and roles and members tables into the codefirst domain - which means writing a membership provider in code-first.
Luckily there is a project for that http://codefirstmembership.codeplex.com/ although its not a perfect implementation. The original is VB, look in the Discussion tab for my work on getting it running in c# MVC.
I'm working with the author on a better implementation that protects the membership data (password, last logged on date, all of the non-allowed data) but allow you to map and extend the user table. But its not ready yet!

You don't really need to use Entity Framework to access aspnet_membership provider accounts. You really just need to create an instance of the membership object, pass in a unique user identifier and a Boolean value indicating whether to update the LastActivityDate value for the user and the method returns a MembershipUser object populated with current values from the data source for the specified user.
You can then access the username by using the property of "Username".
Example:
private MembershipUser user =
Membership.GetUser(7578ec40-9e91-4458-b3d6-0a69dee82c6e, True);
Response.Write(user.UserName);
In case you have additional questions about MembershipProvider, you can read up on it on the MSDN website under the title of "Managing Users by Using Membership".
Hope this helps you some with your requirement.

Related

Nest TypeORM Postgres update user's column('number of posts') based on the userId in the Posts Table

I'm wondering if it's possible to auto update the User's column('number of posts') if the Posts table updates. The Post entity has a ManyToOne relation with User('userId'). Is there a way to make the User Table "listen" to the Post Table and automatically updates the number of post column, or i need to write it in the post service create function to do so. I'm new to sql so i'm just trying new stuff. I'm using NestJS,typeORM, Postgres and Graphql
#Kendle's answer does work and has the advantage of pushing the computation and complexity down onto your DB server. Alternatively, you can keep that logic in the application by leveraging TypeORM's Subscribers functionality. Documentation can be found here.
In your specific use case, you could register a subscriber for your Post entity implementing afterInsert and afterRemove (or afterSoftRemove if you soft delete posts) to increment and the decrement the counter respectively.
You don't want to duplicate that data. That's the whole idea of a relational database that different data is kept in different tables.
You can create a view if you want to avoid typing a query with a JOIN each time.
For example you might create the view below:
CREATE VIEW userPosts AS
SELECT
user.id,
user.name,
COUNT(posts.id)
FROM users
LEFT JOIN posts ON user.id = posts.user_id
ORDER BY user.id;
Once you have created the view your can query it as if it were a table.
SELECT * FROM userDate WHERE id = '0001';
Of course I don't have your table definitions and data so you will need to adapt this code to your tables.

How to use Entity Framework with a database without relationships defined

I am new to EF so please bear with me. I am using Entity Framework with an existing database in which the relationships are not defined.
Using EF, I am able to produce the model, but obviously the 'navigational properties' are not working. Is there a way I can specify the mapping between the entities?
For example, in my Product entity, I have a field CategoryID_fk (maps to Category entity). But since the relationships are not defined, I cannot load a Category while loading a Product entity.
Can someone guide me in this regard?
I do understand that it would be preferable to refactor our database but I am unable to do that now. Thanks in advance.
This link is very useful.http://www.entityframeworktutorial.net/
I think field names are not suitable conventions.Try to change field name as CategoryId or Category_CategoryId .I think it will work
Yes, you can do a group join. Basically you will retrieve Products and Category in separate queries and take an approach as indicated in this answer.
Something along these lines:
var productCategoryList = products.GroupJoin
(
categories,
p=> p.productId,
c=> c.CategoryId,
(p, c) => new ProductCategory
{
//Create your Product Category model here
}
).AsEnumerable();

Entity Framework inheritance from SQL Membership

I am using Entity Framework 3.5. I have created an object that calls "Persons" that is inherited from SQL Membership table (aspnet_Users), they are linked by UserId (Guid) with 1-to-(0..1) relationship and they both belong to "UserSet".
Say, I have an existing "aspnet_User" called "jsmith" in the membership database already. How can I create just the "Person" (child) that links it to "jsmith" in entity framework?
Guid guid = new Guid("xxxx-xxxx-xxx..") // jsmith Guid
User user = GetUserByGuid(guid); // Assuming a function gets "jsmith" as "User"
// Try 1:
Person person = new Person();
person.UserId = guid;
context.AddToUserSet(person);
context.SaveChanges(); // This doesn't work and throws an error
// Try 2:
Person.CreatePerson(person); // Doesn't work either, because it creates a whole new user
context.SaveChanges(); // Throws an error
I even tried to create an EntityKey and use detach/attach, didn't work either. Am I doing anything wrong? Any help is appreciated.
R.B.
You should not put SQL membership into your entity model. ASP.NET membership is intended to be pluggable; you can swap out the SQL membership provider for, say, an OpenID or domain authentication provider. Mapping the SQL membership tables makes you totally dependent on the specific implementation of one version of that provider, which is bad coupling.
Also, even if you did do this, inheritance is the wrong relationship. A user has an account. A user is not an account. So the correct relationship is composition, not inheritance.
Perhaps "Person" is the wrong relationship in the example. However, if you are talking about extending ASP.NET memembership by adding more properties like "FirstName", "LastName", etc.. this is not totally wrong. There are some articles talk about extending SQL membership and/or creating "Custom Membership" by adding your own db table and then inherited from base MembershipUser class. In that case, it is inheritance.
There are some articles that talks about extending membership, but not on Entity though:
http://www.code-magazine.com/Article.aspx?quickid=0703071
More articles
- codesmart.wordpress.com/2009/03/27/extending-the-microsoft-aspnet-membership-provider/
Also, you may want to consider using Profiles as alternative.

Entity framework linq to entities

Previously when I wanted obtain related data in an sql query I would join tables, however now in linq to entities I want to get data from a table that is related to the table through another table. I don't know how to perform this sort of query in linq to entities. If someone could help that would be good.
The example is a table named person which has a relationship to table users which is related to table roles. I want to be able to obtain a person that has a particular role. Since person is only related to user and indirectly through user to role, I'm not sure of the query. Also using navigation properties doesn't get me all the way there either.
Any information would be good. Here is an example of the database structure:
db structure http://img194.imageshack.us/img194/4540/persons.jpg
If you using the generator in VS (ie, drap drop the data table and diagram and keys are all set in db), then the thing you are asking could be already there automatically.
e.g.
from Person in Context.Persons
where Person.Name == "PETER PAN"
select Person.User.Role.RoleName;
Exact name need to refer to the code generator, but this is the idea. Linq to entities will help to map foreign keys and those for you.
Edit
Actually I haven't tried using include. But according to msdn:include method, the include should show the object hierarchy to work. So, for your query to work, try:
from c in db.Persons.Include("aspnet_Users").Include("aspnet_Roles")
where c.aspnet_Users.aspnet_Roles.RoleName == "Role" select c
And moreover, will you consider start from roles?
from r in db.aspnet_Roles
where r.RoleName == "ROLE"
select r.aspnet_Users.Persons
(from u in db.aspnet_Users.Include("Person")
from c in db.aspnet_Roles
where c.RoleName == "role"
select u.Persons);
Worked it out thanks for trying though.

Adding a property to an Entity Framework Entity from another table

I'm just starting out with the Entity Framework and ADO.NET Data Services and I've run into an issue that I can't seem to figure out. I have two tables, one that has user information and the other that has a created by field. Within the database, there isn't a foreign key between these tables. The user table contains an arbitrary Id, a username, and a display name. The created by field contains the user's username. In my entity I would like to have the user's display name since this is what I need to display and expose over the ADO.NET Data Service? I'm aware that I could restructure the database, but I was hoping that I could do the join using the username as I would in a SQL statement.
Thanks in advance,
-Damien
You can make a view using a join of both tables, and then use this object to display the user's name.
There's some info on mapping custom queries here.