I have existing tables including the mapper table. I have to set the Entity Framework annotations. I am confused about how to achieve that. there are three tables,
Model (ModelId, ModelName),
Department (DepartmentId, DepartmentName)
ModelDepartmentMapper (ModelDepartmentMapperId, ModelId, DepartmentId, ModelStatus)
I have created the classes as:
public class Model
{
public int ModelId { get; private set; }
public string ModelName { get; private set; }
public virtual ICollection<Department> Departments { get; private set; }
}
public class Department
{
public int DepartmentId { get; private set; }
public string DepartmentName { get; private set; }
public virtual ICollection<Model> Models { get; private set; }
}
public class JoinModelDepartment
{
public int JoinModelDepartmentId { get; private set; }
public Guid ModelId { get; private set; }
public Guid DepartmentId { get; private set; }
public int ModelStatus { get; private set; }
}
And in DBContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Model>()
.HasMany<Department>(s => s.Departments)
.WithMany(c => c.Models)
.Map(cs =>
{
cs.MapLeftKey("ModelGuid");
cs.MapRightKey("DepartmentGuid");
cs.ToTable("JoinModelDepartment");
});
}
Please guide me how to add ModelStatus in the mapper table. Do I need to create it manually or there is a way to do this?
What I would tend to do is move these kinds of mappings into their own class files. Theres a brilliant tutorial found here:
https://www.entityframeworktutorial.net/code-first/move-configurations-to-seperate-class-in-code-first.aspx
This lets you map out each of the tables individually and it will build the database off of them.
So in your case you would have a Model, Department and a ModelDepartmentMapper class file. From there you can set all the relevant columns and how they are linked to another table as well as column types IE VARCHAR etc
Related
I have so strange question connected with realization of dictionary (handbook, etc.) with description of, for example, work types. Let me explain.
Let me have 2 classes:
public class Order
{
public Guid Id { get; set; }
public ICollection<WorkType> WorkTypes { get; set; }
}
public class PurchaseOrder
{
public Guid Id { get; set; }
public ICollection<WorkType> WorkTypes { get; set; }
}
where
public class WorkType
{
public int Id { get; set; }
public string Description { get; set; }
}
and my context is:
public class MyDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
public DbSet<PurchaseOrder> { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
When I make a migration, I get 2 additional columns in my WorkType table: OrderId and PurchaseOrderId.
So, I don't want to have them in this table, of course. Is it possible to make this N:M relation without FK?
Possible I can have WorkType collections in many classes.
Thank you.
P.S. I use EF Core 6.0.6
I try to create the following database design with EF Core 3.1 (code-first)
Entity "Recipe" can have a list of type "Resource" and a single type of "NutritionFacts"
Entity "Ingredient" can have a single "NutritionFacts"
Entity "Instruction" can have a list of type "Resource"
But I found no way to implement this without having multiple "NutritionFacts" or "Resource" tables. (RecipeNutritionFacts-/IngredientNutritionFacts)
And I also don't want to blow up my "Recipe" or "Ingredient" tables with the columns from the "NutritionFacts-/Resource" entities. (owned types)
Goal: I would like to reuse the tables "Resource" and "NutritionFacts" in multiple entities.
If I delete a "Resource" from the collection in entity "Recipe" or "Instrucion" then the corresponding "Resource" entity should be also deleted. (recipe.Resource.remove(x))
Same for a "NutritionFacts" from entity "Recipe" or "Ingredient" (recipe.NutritionFacts = null)
I already tried several combinations with owned types, etc... but with no success.
Any ideas for a good implementation to reach this goal?
Example Classes:
public class NutritionFacts
{
public int NutritionFactsId { get; set; }
public decimal Kcal { get; set; }
public decimal Fat { get; set; }
}
public class Resource
{
public int ResourceId { get; set; }
public string Path { get; set; }
}
public class Ingredient
{
public int IngredientId { get; set; }
public string Title { get; set; }
public virtual NutritionFacts NutritionFacts { get; set; }
}
public class Recipe
{
public int RecipeId { get; set; }
public string Title { get; set; }
public virtual NutritionFacts NutritionFacts { get; set; }
public virtual ICollection<Resource> Resources { get; set; }
}
public class Instruction
{
public int InstructionId { get; set; }
public string Title { get; set; }
public virtual ICollection<Resource> Resources { get; set; }
}
Example Context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// variant-1 owned
modelBuilder.Entity<Ingredient>().OwnsOne(x => x.NutritionFacts).HasKey(r => r.UniqueIdentifier);
modelBuilder.Entity<Entities.Recipe>().OwnsOne(x => x.NutritionFacts).HasKey(r => r.UniqueIdentifier);
// variant-2
modelBuilder.Entity<Entities.Recipe>()
.HasOne(p => p.NutritionFacts).WithOne();
modelBuilder.Entity<Ingredient>()
.HasOne(p => p.NutritionFacts).WithOne();
}
I'm trying to have multiple tables with the same schema, within the same database, using Entity Framework.
For example, if I have the classes below, and I login to the SQL Server database, I can only see a table that is named something like dbo.Schema.
Is there a way to have multiple tables with the same schema?
class Context1 : DbContext
{
public DbSet<Schema> table1 { get; set; }
}
class Context2 : DbContext
{
public DbSet<Schema> table2 { get; set; }
}
class Schema
{
[Key]
public int EntryId { get; set; }
}
Is there a way to have multiple tables with the same schema?
You can either use Data Annotations or Fluent API to configure the table and schema name.
Suppose you have the following model:
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Using Data Annotations, you could name it blogging.blogs:
[Table("blogs", Schema = "blogging")]
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
Using Fluent API, you can override OnModelCreating method to name it blogging.blogs:
class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.ToTable("blogs", schema: "blogging");
}
}
You can simple do like this with multiple tables.
public partial class AdventureWorksEntities : DbContext
{
public AdventureWorksEntities()
: base("name=AdventureWorksEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Address> Addresses { get; set; }
public virtual DbSet<AddressType> AddressTypes { get; set; }
public virtual DbSet<Contact> Contacts { get; set; }
public virtual DbSet<ContactType> ContactTypes { get; set; }
public virtual DbSet<CountryRegion> CountryRegions { get; set; }
public virtual DbSet<StateProvince> StateProvinces { get; set; }
}
in this code we can add more table from same database. There is no need to create another class and inherit DbContext.
or you can do Add Item into project-> New Item->Data->ADO.NET Entity Data Model.
This will generate same code with your selected tables.
Thanks
I have two tables one with a list of clients and the other whether they are active or not. I want to link them Entity Framework, however, I am struggling. The two tables were already setup and have to primary keys or foreign keys.
namespace DataWarehouse.Models
{
public class DatabaseList
{
[Key]
public string STARDB { get; set; }
public int DBClientID { get; set; }
public string ClientName { get; set; }
public DatabaseStatus DatabaseStatus { get; set; }
public ICollection<PayComponents> PayComponents { get; set; }
= new List<PayComponents>();
}
public class DatabaseStatus
{
[Key]
public string STARDB { get; set; }
public string STATUS { get; set; }
public DatabaseList DatabaseList { get; set; }
}
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options)
: base(options)
{
}
public DbSet<DatabaseList> DatabaseList { get; set; }
public DbSet<DatabaseStatus> Status { get; set; }
public DbSet<PayComponents> PayComponents { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DatabaseList>()
.HasOne(p => p.DatabaseStatus)
.WithOne(i => i.DatabaseList)
.HasForeignKey<DatabaseStatus>(k => k.STARDB);
}
}
}
I was hoping that Entity Framework would see the columns STARDB and notice that it is the same in both tables and match them that way. All I want to is to add the Status column from DatabaseStatus into the Databaselist table.
Thanks.
Managed to figure it out. My database was setup properly. However, I forgot the include statement in my Repository.cs class.
public IEnumerable<DatabaseList> GetAllClients()
{
_logger.LogInformation("Get all clients was called");
var clients = _ctx.DatabaseList
.Include(d => d.DatabaseStatus)
.OrderBy(p => p.ClientName)
.ToList();
return clients;
}
Still new to C# so a bit of learning curve!
I have the model:
public class Movie
{
[Key]
public int MovieId { get; set; }
public string Title{ get; set; }
public ICollection<Actor> Actors { get; set; }
}
public class Actor
{
[Key]
public int AtorId { get; set; }
public string Nome { get; set; }
public ICollection<Movie> Movies { get; set; }
}
and the context:
public class MoviesContext : DbContext
{
public DbSet<Movie> Movies { get; set; }
public DbSet<Actor> Actors { get; set; }
public MoviesContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<MoviesContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Movie>().
HasMany(m => m.Actors).
WithMany(a => a.Movies).
Map(
m =>
{
m.MapLeftKey("MovieId");
m.MapRightKey("ActorId");
m.ToTable("ActorsMovies");
});
}
}
The table "ActorsMovies" is already created on sql server. how do I insert data into this table with entity framework? To insert data on the table Movies, for example, i've used the code db.Movies.Add(movie) and db.SaveChanges()
}
movie.Actors.Add(actor);
db.SaveChanges();
This should allow you to update the many to many table.