EDMX is overwriting Key data annotations - entity-framework

This applies to EF 5 and database first modeling. My model was built useing the EF generator from an existing DB.
I'm using the [Key] data annotation in my model classes because the primary key fields have names that are not in line with EF conventions.
Everything works, but when I open the root EDMX files, the model classes are updated and any manual changes I had made are lost.
Should I be making my changes in a different manner?

You could update your T4 template to add in the data annotation for you on primary keys?
if (simpleProperties.Any())
{
foreach (var edmProperty in simpleProperties)
{
if (ef.IsKey(edmProperty)){
#>
[Key]
<# } #>

the solution that worked for me was to overide the EF convention in OnModelCreating method in the context class.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<abk_Bookings>()
.HasKey(e => e.booking_number);}

Related

How can I examine and edit an entity's properties from PropertyBuilder?

I'm writing a mapper to map data types between different databases.
When iterating through entities after they have been set by OnModelCreating I need to examine these entity property values that have previously been set by HasColumnType and HasDefaultValueSql in order to alter these settings in a generic way.
How can I read and change these properties?
I'm currently using this function as a first approach:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
foreach (IMutableProperty prop in entity.GetDeclaredProperties())
if (prop.ClrType == _byteArrayType)
modelBuilder.Entity(entity.ClrType).Property(prop.Name).HasColumnType("VARBINARY");
}
But that's not the best approach. I need to read (and alter) the original SQL value that has been set (e.g. XMLType data type or SYSDATE default value.)

To add navigation property without foreign key in EF Core, DB-first migration with .NET Core Web API

I am working with an existing system and updating it to .NET Core, Web API and EF Core.
The existing system has 2 tables:
Parent table: Id, name, etc..
Child table: Id, ParentId, name, etc..
Though ParentId exists in the child table, there is no foreign key reference, but I want to be able to use include when I query the parent. I have asked not to add FK as part of deleting they are putting -ve values to parentId column. This way they can bring it back and a legacy system was built that way.
Now, in db-first migration how can I specify a navigation property without fk so my EF Core to act relational; or at least return them together. Adding nullable foreign key is not an option as it will break the system when -ve values are added.
I do have suggested for full cleanup of DB and getting rid of -ve values but that involves lots of testing and no deliverable. So long story short how to add navigation property without foreign key in database first migration ?
I tried adding collection and virtual entry in the model, but after migration it got overwritten. I have added this by using HasMany on modelbuilder as per this document - https://learn.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key
But scaffolding is overriding my navigation property
I found out the answer for this.
In EF core 3.x the dbcontext created by DBFrist scaffolding is all partial classes.
So I did the following:
1. new partial class for context class - here i added the relationship of navigation property using OnModelCreatingPartial() method. Example below
public partial class dbContext : DbContext
{
partial void OnModelCreatingPartial(ModelBuilder builder)
{
builder.Entity<Packcomponent>()
.HasOne(p => p.Pack)
.WithMany(b => b.PackComponent)
.HasForeignKey(p => p.PackId);
}
}
extended the partial class in a new file and added navigation property there.
public partial class Packcomponent
{
public Pack Pack { get; set; }
}
public partial class Pack
{
public List PackComponent { get; set; }
}
This way upon scaffolding it did not overwrite custom navigation properties and I also could use this properties to do EF operations like .Include() and to save related entities as well. It is pretty awesome!!

Change Entity Framework Migrations table name

I am using Entity Framework 7 and I would like to rename
"__EFMigrationsHistory"
table name to
"__Migrations".
So I have the following on my context:
protected override void OnModelCreating(ModelBuilder builder) {
base.OnModelCreating(builder);
builder
.Entity<HistoryRow>()
.ToTable("__Migrations")
.HasKey(x => x.MigrationId);
// Remaining configuration
}
I am able to create the migration but when I apply it to the database I get:
There is already an object named 'PK_HistoryRow' in the database.
Could not create constraint or index. See previous errors.
I have been trying a few options but I always end with a problem.
Does anyone knows the best way to do this?

ef6 database migrations change table name

I am using EF6 code first and database migrations to keep my new database up do date.
I wanted to change the name of one of the database tables from "contacts" to "contact".
So in EF I change the name of the class and in the customised DBContext class I rename Contacts to Contact so it is now showing;
public DbSet<Contact> Contact { get; set; }
However I run the database migrations with Update-Database -Verbose -Force and no change is made.
To find out what is going on I put a new field in, and it tries to update the Contacts table rather than Contact which it needs to create.
So how do I fix this?
Try removing Pluralizing:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
I found the answer which is to use the following attribute in from of the class declaration;
[Table("Contact")]

Why does the Identity v2 naming schema differ between EF and AspNet?

I wonder if anyone out there can help me with the following problem...
I have a created a EF code first database (sqlexpress) that uses Identity v2 -I can see within that database all my models, including the Identity related tables starting with Identity* (ie. IdentityUserClaims, IdentityUserLogins, IdentityUserRoles IdentityRoles & IdentityUsers).
I then create a brand new MVC project as well as adding the same connection string. When I register a new user -for some reason it goes off and creates Identity v2 tables starting with AspNet* (ie. AspNetUserClaims, AspNetUserLogins, AspNetUserRoles AspNetRoles & AspNetUsers).
[I am using... EF 6.1.1, Identity 2.1, MVC 5.2]
Why does the Identity naming schema differ between EF and AspNet ? how do I make MVC use the EF schema Identity* ?
You can override table names by [Table("MyUsers")] attribute on top of your classes:
[Table("WhateverILikeUsers")]
public class ApplicationUser : IdentityUser
{
}
Or you can rename tables in DbContext:
public class MyContext : IdentityDbContext<ApplicationUser>
{
// other stuff
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ApplicationUser>().ToTable("HelloIdentity");
}
}