Using Fuelt API to create a database with Code First approach - entity-framework

I'm trying to create a database with Code First approach. Reading some tutorials they use Fluent API but when I try this it shows a "missing a reference" message on "HasForeignKey".
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>()
.HasForeignKey(p => p.FKId);
}
My solution set up is that I have a DAL project with all database related stuff and a .NET Core 2.2 WebApplication. How can I use Fluent API?

Related

Entityframework Code First Singularize table name

I've tried the way it's mentioned in
EF4 Code First make tables names singular but in my case EF6 is not recognizing OnModelCreating(). It says "No suitable method found to override". Is there any alternate way or any way to fix it?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
I am not certain of the ModelBuilder Type but I can say for a fact I just tested my older Code First on EF 6.1.3 and it works fine with this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("dbo");
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
...
}
I think you needed DbModelBuilder versus ModelBuilder. I am not sure of that thread but know I just ran mine just now and that was the only thing I noticed differently. I learned EF Code First from two tutorials and this one by far was better than the other by leaps and bounds: http://www.entityframeworktutorial.net/code-first/entity-framework-code-first.aspx

Entity Framework - Existing Database, classes in seperate library

I'm looking for information about using entity framework with an existing database, but to keep my poco classes in another library.
I've done this a number of times in the past, but I've always ended up with my model classes in my data access library using EF and my domain classes in a separate library. Inevitably this meant writing code to translate between my domain classes and my model classes. This seems pointless and inefficient since the classes are usually almost identical.
Can anyone point me to a walkthrough keeping my classes are materialized by EF in a separate library? I would need to be able to do some minor name correction (eg Filter_Rule --> FilterRule). I would also like to be able to keep anything EF specific in the data access library so that I can swap out the data access library if I need to.
Thanks,
Jason
This should be quite straightforward. Create a DbContext code-first style as normal, adding DbSets and configurations as necessary to tell EF about your database. Set your initializer to null so it doesn't try to mess with your existing database, and voila...
public class YourContext : DbContext
{
public DbSet<YourPoco> YourPocos { get; set; }
static YourContext()
{
Database.SetInitializer<YourContext>(null);
}
public YourContext() : base("database_name")
{
}
protected override void OnModelCreating(DbModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<YourPoco>().Property(x => x.FilterRule).HasColumnName("Filter_Rule");
//OR
builder.Configurations.Add(new YourPocoConfig());
//OR
builder.Configurations.AddFromAssembly(typeof (YourContext).Assembly);
}
}
public class YourPocoConfig : EntityTypeConfiguration<YourPoco>
{
public YourPocoConfig()
{
HasKey(x => x.Id);
Property(x => x.FilterRule).HasColumnName("Filter_Rule");
}
}
If you are worried about getting everything to match your database structure, you can use Entity Framework Tools for Visual Studio to reverse engineer your models, then match the configuraiton or copy the generated POCO's into your other library and convert the data annotations into respective EntityTypeConfiguration classes to keep the POCO's clean.
MSDN document on reverse engineering code-first.

Pluggable conventions in a database first environment

Working with entity framework 6+ we now have access to add custom Conventions to the model builder like this.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(FilterConvention.Create<ITenantOwned, Guid>("TenantOwned", (e, tenantKey) => e.TenantKey == tenantKey));
modelBuilder.Conventions.Add(FilterConvention.Create<ISoftDelete>("SoftDeleted", e => e.Deleted == false));
base.OnModelCreating(modelBuilder);
}
However I am unable to get this to work because all of our projects have an EDMX file. When you allow your metadata to be read in through the goofy connection string OnModelCreating never gets called. I am fine with OnModelCreating never getting called except that so far as I can tell I am unable to access the modelBuilder at any other time in order to inject my own Conventions into the model.
So is is it actually the case that Conventions are unavailable to non code first users, or am I overlooking something.

How to exclude one table from automatic code first migrations in the Entity Framework?

I'm using the Entity Framework in the Code First mode with automatic migrations enabled. Now, I have one entity whose table should not be managed (migrated) by the EF. Is there a way of disabling automatic migrations for one specific entity (i.e. table)?
This is now possible in EF Core 5.0 using the ExcludeFromMigrations() method, but strangely enough you have to call the ToTable() method and then use the TableBuilder.
https://devblogs.microsoft.com/dotnet/announcing-entity-framework-core-efcore-5-0-rc1/#exclude-tables-from-migrations
public class ReportingContext : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().ToTable(nameof(Users), t => t.ExcludeFromMigrations());
}
}
Another option that worked for me in EFCore 5.0 is to use SetIsTableExcludedFromMigrations:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().Metadata.SetIsTableExcludedFromMigrations(true);
}
My TEMPORARY solution, only for dev environments.
I have a separate script that runs migration and program run does not check them. So in unexpected case I was possible to invoke Ignore<ContactView>() and run migrations with this line. When it was completed, I removed this line!
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// comment out this code after migrations are done
modelBuilder.Ignore<ContactView>();
}
It is possible by using another DbContext to access the table in question. Migrations are bound to one DbContext (see Is it possible to have automatic migrations for one DbContext and not for another in the same project?).
Not sure if this is the OP's exact scenario, but I had a table that I did not want a migration generated for. I accomplished this by using ToView instead of ToTable within the DbContext:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyTable>(entity => {
// Migration will not be generated for this table
entity.ToView("MyTable", "dbo");
entity.Property(e => e.FooBar).HasColumnType("DECIMAL(19,9)");
});
}
It feels a bit hacky to me, but maybe it's not -- because, after all, I'm just trying to "view" the table, not write to it...
[Tested with .NET Core EF 3.1.3]
You want to use the [NotMapped] annotation on that class/entity.

entity framework plural table names

I am trying to get EF 5 to generate singular table names. I have the following code in my DbContext...
public partial class LiveoModelContainer : DbContext
{
protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
}
We are using Model First, and have our own generated code to follow our internal development patterns. So we are not using the out of the box code gen that comes with EF. I have set pluralization to false in the edmx properties, in the Database Tools/O/R Designer, and removing the convention in the OnModelCreating above. However, the table names remain plural.
How do I fix this?