missing Navigation property in auto-generated entity class - c#

I am moving my first steps in the Entity Framework 4.0, and I am currently facing an annoying issue.
The authentication/authorization process of my application is based on the standard ASP.NET membership provider, in other words the database is the well-known ASPNETDB.MDF. In this database there are - amongst others - the tables aspnet_Users and aspnet_Roles, which are linked together by the table aspnet_UsersInRoles.
I generated a new "ADO.NET Entity Data Model", I selected Generate from Database, I provided all the necessary parameters, and the wizard generated for me the relative .EDMX file. I named this "SecurityModel". In the aspnet_User entity I can see there is a navigation property that should retrieve all linked Roles, and viceversa.
At this point I added a new "Domain Service", in my case SecurityDomainService.
When I was asked, I selected the SecurityModel, and all the tables it contains.
Even in this case the wizard generated the SecurityDomainService for me.
Apparently no problems at all. However, I realized that in the entity aspnet_User I have all navigation properties (Membership, Profile, Applications, etc.) but Roles.
I read somewhere that EntityFramework doesnt handle many-to-many relationships. However I can see in my Entity Data Model that an Association exists between aspnet_Roles and aspnet_Users, and it is based on aspnet_UsersInRoles. I can also see in the Data Model designer the "Roles" navigation property in the User entity.
So, my question is why has not this navigation property been generated?
Thanks in advance for all your help.
Cheers,
G.

The problem here is that the aspnet_UsersInRoles table contains only the primary key fields of the tables in the many to many relationship. Entity Framework 'inlines' this table and does not represent it as an entity. Entity Framework handles this fine - it is RIA services that does not support this type of relationship.
Simply adding one extra field to the table will prevent it from being inlined and result in an aspnet_UsersInRoles being generated. This will be supported within RIA Services.
You will need to be careful modifying the aspnet schema to ensure that you do not break any of the stored procedures etc but the addition of a nullable bit column should not cause too much disruption.

Related

Entity Framework 6 add existing complex type to key columns

I'm working on a project using EF 6 built using database-first approach. There are several tables that previously had the same 3 properties mapped to a complex type (used in several places throughout code). These properties were designated as "foreign key" columns, although their parent-child relationships were never defined in the database.
Recently, a co-worker went through and formally defined the relationships between the FKs and their parent tables in SQL Server. I am now attempting to update the entity model (update from database), and the new associations did not appear. I have resorted to removing the tables from the model and re-adding them. They now show the proper associations.
However, the mapping to Complex Type is gone. When I try to add it back, the updated mappings destroy the associations on those properties (I get a model error when saving). I am aware that Complex Types do not support associations.
Is it recommended to first remove the associations for the columns prior to re-mapping them to the complex type? Will EF observe the underlying key relationship even though the columns are not visible on the entity?
While I would still like to get some feedback on my questions, here's what I did to solve my issues.
1) Removed the associations generated by EF when deleting and re-adding tables from the database. Note that these relationships are only for the foreign key fields which were to be replaced by the complex type.
2) Followed the MS steps (found here) to refactor the requisite key properties to a complex type
3) Optional: It was necessary for me to edit the EDMX directly as XML in order to remove some lingering associations that could not be repaired with the designer
So far, my model functions as intended. I believe the FK relationships are observed during CRUD operations.

Entity Framework Core mismatch in column name

I am trying to do a many-to-many relationship. I have a Customer that can be connected to several CouponCollections but I don't get it to work. I didn't write the code myself and haven't worked with EF that much earlier.
The current error I have, tells me "Invalid column name 'CustomerId'" in CouponCollection when I try to access it. That table has never had a 'CustomerId' column either in the database or in the object, as far as I know.
Is it possible to see how EF is handling the columns and why it thinks that this column should exist? Maybe resetting it and force it to reevaluate all columns.
On a sidenote I don't get migrations to work either. Maybe the problems are connected, but the database just won't update when I change something in the model.
From the docs
Many-to-many relationships without an entity class to represent the join table are not yet supported. However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.
Emphasis mine
Given your issue, you probably need to create the entity to represent the join table as described above.

ASP.NET MVC - Using Identity with existing, modified AspNetUsers table

At my company the DBA updates our SQL Server tables to add columns, etc and when pushing these changes to prod. In my scenario we have an existing AspNetUsers table and other Identity-related tables. This existing AspNetUsers table has additional columns added (FirstName, LastName, Joined date) and the id column was changed to an int.
I'm writing a new MVC Web Api (VS 2013) on top of this existing database and I started with the default Web Api template that uses Identity which I really like. I can't use Code-First since the tables already exist and already have these additional fields. I will not and cannot have my code update the DB through Nuget, and I'm not responsible for creating DB scripts either.
My question is: How can I have my code work with an existing AspNetUsers table that has additional fields that I'll need to capture when registering the user? I've added the new properties to the IdentityModel.cs inside of ApplicationUser : Identity User. I've also added these fields to my AccountController's Register method and the AccountBindingModel's RegisterBindingModel class. The error I'm getting when registering the user is "Mapping and metadata information could not be found for EntityType Phoenix.WebAPI.Models.ApplicationUser" and I don't know how to approach this since I'm not allowed to touch the DB and don't want to use Code-First.
Well, let's see:
At my company the DBA updates our SQL Server tables to add columns
As far as I understand about IT positions, an DBA should not do that. Database modelling is a job for an Analyst.
I can't use Code-First since the tables already exist and already have
these additional fields
That is not right. You can use Code-First in a existing database, it also works way better than EDMX. EDMX has been discontinued in EF7.
However, if you really don't want to use Code-First, take a look at this library https://github.com/kriasoft/AspNet.Identity it might be helpful.
You can try to use Fluent API to map your entities to database tables.
fluent api

Adding an entity (and respective table) to EF DB-first model

I'm pretty new to Entity Framework: I started from a database-first model to maintain an application created using a strange mixture of EF and plain old SQL.
I created my own fresh DB-first model and I'm fine with it. Today my boss asked me to add a new entity. Lack of foreign keys simplifies the scenario.
I have created my new entity in the diagram (it's made of three instances of a Complex Entity I just created) but now I have to make an incremental DB script to create the new table. I'm supposed to do that both for MySQL and SQL Server but let's start with the second.
So now I see that I have a compilation problem "No mapping for entity Entity" and if I use "Update model from database" command I see no option for pushing changes to DB, but that sounds correct given the word "from".
OK, I have tried to click "Table Mapping" from the right-click menu and I found the option to map the entity to the table. I was going to type the new table name in the "Add table or view" field and... WAIT! I can only select existing tables
I understand it's just for a single table so I can simply "Generate database from model" in order to get the full SQL script, find the table I want, run that to DB and "Update model from DB" so EF will see the table, BUT
I would like to understand how to create incremental scripts with Entity Framework. That is my question.
You indicate you have a database-first design but appear to be working from a code-first mindset.
In database-first design the entity model is subordinate the underlying datastore. Changes to the model (or at least changes to the model which also require changes to the underlying datastore) occur FIRST on the database.
So how do you create a new table for the entity? You create the new table in your database (CREATE TABLE ...). Then using the "Update Model From Database" wizard you select the new table from the "Add" tab. EF will create the corresponding EF class automatically. If you already manually created the entity you should delete it otherwise you could end up with some weird entity naming (i.e. Customer1).
Database first does not have the capability to support table creation at the entity layer. Changes to the database are always one way, from the database to the entity model, hence the term "database first".
On the other hand if you are more comfortable creating entities directly and want to build a database from a set of entities you should be looking to create a "Code-First" design. Despite the name "code first" it is possible to get an initial set of entity classes from an existing database. The term "code first" refers to the origination of changes to the db/model structure.

Can I load SimpleMembership classes into EntityFramework?

I've been trying to load the standard ASP.NET SimpleMembership (SM) classes into my EntityFramework (EF) model, but keep running into a few brick walls. I want to use the UserProfile table as a class in my model to bind applications to certain users, then let an admin decide which user can see/edit specific applications.
The way I'm doing it now is running the EF-generated .sql over the .mdf file ASP attaches to the DB at runtime. Then run 'Update Model from Database' in EF. The result is the following pic:
The User class should be replaced with UserProfile (and UserType by Roles), but this won't run because of ambiguity between the EF UserProfile and the SM UserProfile. ASP's internal code can't seem to handle that:
The mapping of CLR type to EDM type is ambiguous because multiple CLR
types match the EDM type 'UserProfile'
I've tried renaming the UserProfile entity to something like aspnet_UserProfile, but it results in EF not being able to find the corresponding table (because that's still named UserProfile and it should because that's where SM reads).
Is this even possible? Or am I approaching this from the wrong angle?
Small side-question: why is the .mdf a standard MVC project uses so small compared to the classes the aspnet_regsql.exe tool adds?
EF doesn't allow you to have class that differs only by namespace. You can rename the entity as you did but change the mapping so the table name is still UserProfile.
See mapping details window. Another option is to let the mapping unchanged (after changing entity name so you have a table name different from 'UserProfile') and specify it in the initialisation of your identity provider WebSecurity.InitializeDatabaseConnection.
The table you see are simplified and allows better integration than the old way to do SQL Membership (aspnet_regsql). If you want more information about new identity and background on membership, see the Introduction to ASP.NET Identity
Note that the Simple Memebership provider comes with :
It was hard to persist membership system data in a non-relational
store.
You can't use it with OWIN.
It doesn't work well with existing ASP.NET Membership providers, and
it's not extensible.
Entity Framework uses only class names to identify the type mapped in EDMX and namespaces are ignored - it is a convention to allow mapping classes from different namespaces to single model. From your description, it seems that you would have two same named entities and because of the reason I mentioned above, it throws the error.
But you can name your classes in BLL differently (You have used classes with the same name - EF uses only class names to identify the type mapped in EDMX (namespaces are ignored)) and rename the entities as the workaround.

Categories

Resources