We are in the database design phase of a project using EF4/5 (and RIA Services to Silverlight).
Our current schema has tables like: Applications, Users and Accounts
In .NET I get naming conflicts to existing objects , and have to specify my own object eg: System.Windows.Application
EntityQuery<Customer.Web.Application> queryApplicationT32 = custDomainContext.GetApplicationsQuery();
Question: Is it best practice to do this, or to map in EF to something else eg CustApplication?
If Application, User and Account are real meaningful names in your domain, you should use them.
You will only have a name conflict when you have using statements for both classes:
using Customer.Web;
using System.Windows;
If you only use one of them you won't have a conflict. If you use both, you will have to fully specify your class name.
You can also use an alias: using myAlias = Customer.Web; That way you can specify which class to use by using a shorthand alias.
Related
EF6 has now released the ability to do temporal tables within the configuration and fluent api using the .ToTable(e => e.IsTemporal()) which is great and has worked for all the tables in my model.
However I'm using Identity Model (AspNetUser, AspNetRole, etc...) and those tables don't have that setup to use the .ToTable syntax to make them temporal; it looks like I have two options on how to make those temporal in the EF6 world; but I was hoping for a better option and was wondering if anyone knows of the ideal (or at least recommended) method
Option 1: Manual SQL Statement
In a migration I can do something like migrationBuilder.Sql("ALTER TABLE AspNetUser SET(SYSTEM_VERSIONING = ON (HISTORY_TABLE = AspNetUserHistory))"). This is fine, but is manual and doesn't seem like it would be the recommended method.
Option 2: Explicit Creation of Tables with Inheritance
In my model I could create objects for all the Identity Model types (the public class ApplicationUser : IdentityUser) and then map those to the same table name and include the (e => e.IsTemporal()); but that means creating all those objects which just inherit but don't add anything just to get temporal tables (hoping there is a better way)
Option 3: Recommended Microsoft Method
I wasn't able to find a recommended method to do this; hoping that it is something that does have a standard / recommended solution
Utilisation of Identity Object Directly
It looks like we can use the Microsoft.AspNetCore.Identity namespace directly to create those temporal tables like this
modelBuilder.Entity<IdentityRoleClaim>().ToTable(e => e.IsTemporal());
I'm using Entity Framework for the first time. I'm using Code First development with an existing database. Everything is working great but I do not like using the table name as the class name. The database tables do not making for friendly class names in C#. Is it common place that people rename the classes that are auto-generated by EF? Will this cause problems down the line in some capacity that I am not anticipating? FWIW, I'm not worried about future schema changes to the tables.
I Google'd a few times but no one seems to have asked this before. Maybe I should take that as a sign....
You can use either data annotation attributes:
[Table("tblFoo")]
public class YourEntity
{
}
Or fluent api
modelBuilder.Entity<YourEntity>()
.ToTable("tblFoo");
to provide table name which entity maps to.
I'm attempting to use the Simple Membership Provider with MVC 4 as "by the book" as possible. Here is the current scenario:
-- I've been using Jon Galloway's blog post on the topic here.
1) I'm aware this thing is wired via Entity Framework. I did notice, however, that when I added properties to the UserProfile class, they didn't appear in the table automatically when it was generated. Is this due to the database already being generated (tables were not present)? I manually added the fields and it was functional, but would be nice to know the "gotchas" that would result in the fields not being automatically created.
2) As far as the roles, it seems that it is geared primarily towards a global permission type thing (ie user is a User, Admin, etc.). In the event that you want to make it handle at a project level (ie admin for project1, user for project2), what modifications need to be made?
etc) Is there an article that really goes into detail in regards to best practices on how to extend it?
1)I find the UserProfile table part of Simple Membership a little complicated (in a good way), but it has worked great for my apps.
The convention for Simple Membership is to create a UserProfile table named "UserProfile" with two fields, UserId and UserName. You can configure a different table name or different UserId and UserName field names for the UserProfile by modifying the WebSecurity.InitializeDatabaseConnection() line in Filters/InitializeSimpleMembershipAttribute.cs. You can create a UserProfile table with additional fields and it will be used by Simple Membership if Simple Membership finds that table the first time it runs. Under the default configuration, the first time your app runs SimpleMembership will create the database tables including whatever UserProfile table details specified in Filters/InitializeSimpleMembershipAttribute.cs.
So, the trick is to create the UserProfile table you want (including all the fields you want in that table) before the first call to Simple Membership. This could be created by EF Migrations or created by a database script or even created manually in SSMS.
If you want to dig into the Simple Membership code, see http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/WebMatrix.WebData/WebSecurity.cs and http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/WebMatrix.WebData/SimpleMembershipProvider.cs.
2)I agree with your point about roles and global permissions. Maybe you could use AddUsersToRoles and RemoveUsersFromRoles (in http://aspnetwebstack.codeplex.com/SourceControl/changeset/view/5cb74eb3b2f3#src/WebMatrix.WebData/SimpleRoleProvider.cs) to modify a user's roles at login according to the project they use.
etc)I don't know of a good article on extending Simple Membership, but in principle Simple Membership extends the Extended Membership Provider which extends ASP.NET Membership Provider. You should be able to jump in at an appropriate point.
EDIT in response to Robert's comment:
As a direct answer to why Entity Framework did not create the columns added to the UserProfile class, this happens when the UserProfile table was already created by the SimpeMembership initialization before the app-specific table creation ran. The reason is SimpleMembership has an inbuilt definition of the UserProfile table that is used anytime SimpleMembership creates that table. The timing of the UserProfile table creation is important, so there is a need to make sure the app-specific tables are created before the SimpleMembership initialization runs.
I'm using Entity Framework 5 on ASP MVC 4 web site I'm developing.
Because I am using shared hosting which charge for the number of databases I use I would like to run a test site near my production site.
I have two problems:
1) I use Code First and Database Migration. The migration classes seem to embed the schema dbo inside the name of the tables.
How can I change the schema according to the test/production flag
2) How can I change the schema from which EF select data?
Thank you,
Ido.
Both migration and EF take schema from mapping so if you want to change the schema you must update your mapping to use:
modelBuilder.Entity<MyEntity>().ToTable("MyTable", "MySchema");
and control the value of MySchema from configuration but this is really bad idea. One day you forget to change the value and break your production. Use local database for development and test.
As already said: use identical databases (structurally) for development, test and production.
The goal of schemas is to group database objects, like we do with namespaces in e.g. C#, or to simplify permissions for groups of database objects. Not to identify database stages. By using them for the latter you also make it much harder, if not impossible, to use schema appropriately. See for instance this MSDN white paper.
It is much easier to use some database name conventions to indicate their purpose.
Im currently working in a team that uses EF as the ORM of choice.
We have a common project that contains many EDMX files.
The reason for this is to keep the EDMX files small and manageable while also allowing them to focus on a conceptual set of tables on the database.
Eg
Orders.edmx
Users.edmx
Trades.edmx
These all point to a different set of tables on the same db.
I now need to add the user table to the Trade.edmx file. Since the user table is already in the user.edmx file, this creates the same User type twice under a different namespace which means I would need 2 UserRepository objects.
Common.data.trade.User
Common.data.users.User
Is there a way of avoiding 2 repository objects for the same table?
Any suggestions would be greatly appreciated
If you are using POCO generator you can update template for Trades.edmx to not generate new User class and its context template to use User class from Users namespace. EF matches POCO classes with entities in designer only by the class name (namespace is omitted) so it will work.
The disadvantage is that you have User entity in two mapping files and you must update it in both files or your application throw exception at runtime.
The reason for this problem is your architecture - at the beginning you wanted separated models but know you want to combine entities from different models. Those are contradicting requirements. Either use separated model where Trade knows only userID without any navigation property (like if it is defined in another database) or move all entities to single EDMX to support your new requirements.