Passing generic DBset entities to DbContext - entity-framework

Here is my dbcontext
public partial class MyDbContext : DbContext
{
//dbset 1
public DbSet<Customer> Customers { get; set; }
//dbset 2
public DbSet<Order> Orders { get; set; }
}
I want to pass my models i mean Customer and order outside MyDbContext .something like this :
public partial class MyDbContext<T> : DbContext
{
public DbSet<T> <T>{ get; set; }
}
And a function to get the list of entities to add to my context like this
addEntityToDbContext(Customer)
addEntityToDbContext(Orders)
Is it possible?
I am using EF Core .

I'm not sure what your question is? But DbContext has a generic DbSet method already built in?
public virtual DbSet<TEntity> Set<TEntity>() where TEntity : class =>
(DbSet<TEntity>)((IDbSetCache)this).GetOrAddSet(DbContextDependencies.SetSource, typeof(TEntity));

Related

ASP.NET Core MVC: how to bind entities to a specific user using Entity Framework

I know my question is kinda broad but I haven't found any good answers online.
I am building an ASP.NET Core MVC web app. I am looking for tips on how to bind a specific user to entities (classes in model). The problem is really about how to bind a certain user to a certain entity in the database.
Any help would be greatly appreciated.
ApplicationUser (or IdentityUser) is like any other entity class.
Creating a 1-n relationship, for example, would look something like:
public class ApplicationUser : IdentityUser
{
public virtual IList<MyEntity> MyEntities { get; set; } // navigation property
}
public class MyEntity
{
public int Id { get; set; }
public string CreatedByUserId { get; set; } // FK
public ApplicationUser CreatedByUser { get; set; } // Navigation property
}
You could also do this the fluent way:
public class ApplicationUser : IdentityUser { }
public class MyEntity
{
public int Id { get; set; }
public string CreatedByUserId { get; set; }
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<MyEntity>(b => {
b.HasOne<ApplicationUser>()
.WithMany()
.HasForeignKey(myEntity => myEntity.CreatedByUser);
});
}
}

a query type with the same name already exists

The entity type 'MyType' cannot be added to the model because a query type with the same name already exists.
public class MyContext : DbContext
{
public DbQuery<MyType> MyTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Exception is thrown here
//needed b/c table is not named MyTypes
modelBuilder.Entity<MyType>()
.ToTable("MyType");
}
}
Change DbQuery to DbSet. Keyless Entity Types are used for Views, among other things.
public class MyContext : DbContext
{
//DbSet not DbQuery
public DbSet<MyType> MyTypes { get; set; }
}
Apparently you and I had the same problem on the same day :)
My issue was that I had my view set up as DBset:
public virtual DbSet<VwVendors> VwVendors{ get; set; }
But my mapping was set up as follows:
modelBuilder.Query<VwVendors>()
.ToView("vw_Vendors");
My fix was to do the opposite of what you did. I had to change DbSet to DbQuery.
Your answer helped me get mine :D

How to use abstract classes in EF

I have a DbContext class like
abstract public class CostCenter
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
abstract public Guid ID
{
get;
set;
}
abstract public string CostCenterName
{
get;
set;
}
}
but i cannot run add-migration and update-database commands its give me error , note abstract class is my need here ,
You should derive a new class from CostCenter and add the derived class as a DbSet to your DbContext.
Examples:
[Table("SomeCostCenter")]
public class SomeCostCenter : CostCenter
{
}
And:
[Table("AnotherCostCenter")]
public class AnotherCostCenter : CostCenter
{
}
And, on your DbContext:
DbSet<SomeCostCenter> { get; set; }
DbSet<AnotherCostCenter> { get; set; }
Note that these are set up to use Table-Per-Type (TPT) inheritance to store each derived type in a separate table. There are other options for this such as Table-Per-Hierarchy (TPH) or Table-Per-Concrete class (TPC). You can search on each of these terms to determine which works best in your scenario.
This might be worth a quick read:
http://weblogs.asp.net/manavi/inheritance-mapping-strategies-with-entity-framework-code-first-ctp5-part-1-table-per-hierarchy-tph

Splitting Multiple DbContexts

I have read and seen few projects that talks about splitting or multiple DbContext and I'm not sure what is the best practice.. should I create each DbContext for each entity or have all entity in one DbContext?
this is what I have for now.
public class PersonsContext : DbContext
{
public PersonsContext() : base("name=EmployeeContext")
{
}
public DbSet<Person> People { get; set; }
}
public class OrderContext : DbContext
{
public OrderContext() : base("name=EmployeeContext")
{
}
public DbSet<Order> People { get; set; }
}
Actually you don't need have to create one DbContext for each Entity. But you can have multiple DbContext for a single database. For an example let's say you want to separate your business aspect and security aspect of the application into two different modules. Then of course you can have two different context such as SecurityContext which has all the entities related to Security and BusinessContext consists of Business related entities.
Ex:
public class SecurityContext : DbContext{
public PersonsContext() : base("name=securitycontext"){
}
public DbSet<User> User { get; set; }
public DbSet<Role> Role { get; set; }
public DbSet<Group> Group { get; set; }
}
public class BusinessContext : DbContext{
public OrderContext() : base("name=businesscontext"){
}
public DbSet<Order> Order { get; set; }
public DbSet<OrderLine> OrderLine { get; set; }
public DbSet<Customer> Customer { get; set; }
}

EntityFramework multiple context use single shared table in database

is there any way to share a table in database with multiple context of EF ?
I want to define many models (code first) and bind theme to a single table in a database like this:
public class Context1 : DbContext
{
[Table("Post")]
public DbSet<Post1> Posts { get; set; }
}
public class Context2 : DbContext
{
[Table("Post")]
public DbSet<Post2> Posts { get; set; }
}
public class Context3 : DbContext
{
[Table("Post")]
public DbSet<Post3> Posts { get; set; }
}
all post models are inherited from a basePost for example.