I have been trying the model-first method when designing my application. We usually like to add a prefix to our tables in larger databases so it is easier to find stuff. For example:
sc_ = Shopping cart tables
wb_ = Water billing tables
ea_ = Employment Application tables
The class I have setup looks like this so far.
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
}
Web.config (set currently for local database testing):
<add name="EFDbContext" connectionString="Data Source=.\SQLEXPRESS;Integrated Security=SSPI;Initial Catalog=database" providerName="System.Data.SqlClient"/>
What do I need to change so that the Transaction object gets linked to the sc_Transactions table? I haven't seen in my searching that clarifies this.
As a second question, do I have to manually create my tables?
You can override the OnModelCreating method from DbContext in your EFDbContext class:
public class EFDbContext : DbContext
{
public DbSet<Transaction> Transactions { get; set; }
public DbSet<TransactionItem> TransactionItems { get; set; }
public DbSet<Response> Response { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Transaction>().MapSingleType().ToTable("someTableNameHere");
}
}
See this post for more info.
You can use System.ComponentModel.DataAnnotations like so:
[Table("tblUser")]
public class User
{
public int ID { get; set; }
public string Name { get; set; }
}
Or with EF 4 you can override the OnModelCreating method to map your tables, which is quite powerful thing as you can map and adjust many things at once.
public class MyContext: DbContext
{
DbSet<User> Users { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().MapSingleType().ToTable("tblUser");
}
}
For more info see:
EF4 CF custom database mapping
EF keynotes from the Build2011 event (custom mappings are at about
15 min or so)
Related
I am using ASP.NET Core with Entity Framework Core.
I have a problem with the data model when trying to call a SQL Server procedure.
FromSql method to bind data model is not working if I do not set Key attribute.
This is my code:
Data model class
public class AdminMemberLoginResult
{
public int AdminIndex { get; set; }
public string AdminId { get; set; }
public string AdminName { get; set; }
public bool IsChangePwd { get; set; }
}
DbContext class
public partial class GameContext : DbContext
{
public GameContext()
{
}
public GameContext(DbContextOptions<GameContext> dbContextOption) : base(dbContextOption)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer("data base connection string");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
}
public virtual DbSet<AdminMemberLoginResult> AdminMemberLogin { get; set; }
//public virtual DbSet<DefaultStatisticsResult> DefaultStatistics { get; set; }
}
Snippet of procedure call:
var loginResult = _dbContext.Set<AdminMemberLoginResult>()
.FromSql("exec Game.dbo.sp_admin_getAdminMemberLogin #p_id, #p_pwd",
new SqlParameter("#p_id", id),
new SqlParameter("#p_pwd",pwd)).AsNoTracking().SingleOrDefault();
Key attribute error screenshot:
How can I use FromSql method without Key attribute setting in my data model?
This question is over a year old, but there didn't seem to be a lot of answers out there.
I Just ran across the same issue and I was able to solve this by changing the DbSet to DbQuery in the DbContext.
This is using dot net core 2.1. There are a couple of different approaches that you can read about here: https://msdn.microsoft.com/en-us/magazine/mt847184.aspx
I create a project in MVC 5 with entity framework 6. I am using code first approach. I want in one of the models define a different name for the table then the default. For that I use the System.ComponentModel.DataAnnotationsname space and define the class like this:
[Table(Name="Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
Running the project I get a database with a table with the name AuditoriaDALs. Why the table have this name a not the name that I define?
You are referencing the System.Data.Linq.Mapping.Table attribute when you need to reference System.ComponentModel.DataAnnotations.Schema.Table. So either do this:
[System.ComponentModel.DataAnnotations.Schema.Table("Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
Or better yet:
using System.ComponentModel.DataAnnotations.Schema;
...
[Table("Auditoria")]
public class AuditoriaDAL
{
[Key]
public int AuditoriaId { get; set; }
...
}
https://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations(v=vs.110).aspx
you can set TableName like below :
public class MyContext : DBContext
{
public virtual DbSet<AuditoriaDAL> Auditorias { get; set; }
}
Or in OnModelCreating :
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<AuditoriaDAL>().ToTable("Auditorias");
}
The name= isn't necessary. You should try [Table("Auditoria")].
Wanted to get some clarity on something in regards to how we are implementing our Metadata.
Our Breeze Api is not directly tied to SQL Server so we have implemented a custom EFContextProvider and the DbSet below....
public class MetadataDbContext : DbContext
{
public MetadataDbContext()
: base(nameOrConnectionString: "MetadataDb")
{
Database.SetInitializer<MetadataDbContext>(null);
}
public DbSet<Order> Orders { get; set; }
public DbSet<OrderMeter> OrderMeters { get; set; }
public DbSet<OrderDemand> OrderDemand { get; set; }
public DbSet<MeterHistory> MeterHistory { get; set; }
public DbSet<FieldTech> FieldTechs { get; set; }
public DbSet<Dispatcher> Dispatchers { get; set; }
public DbSet<OrderLookupData> LookupData { get; set; }
public DbSet<Organization> Organizations { get; set; }
public DbSet<Location> Locations { get; set; }
public DbSet<Alert> Alert { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
As you can see I am pointing that DbSet at a database called "MetadataDb" which is just an sdf file we deploy with our project. We then override SaveChangesCore in the Context Provider to route our saves to the correct services instead of going direct to Entity Framework. My question is during some testing we noticed that it seemed Breeze was trying to update the sdf file in some cases. It did not appear that the size of the file changed, but just wanted to make sure before we go to production that the sdf file we are pointing the Metadata at does not grow on our server.
Thanks really enjoy using Breeze.
If the only thing that you are using the .sdf file for is to return metadata then Breeze doesn't do anything more than extract the "edmx" from the ObjectContext or DbContext associated with your database. My guess is that just the act of spinning up the context is causing EF to "modify" the "sdf" file. Breeze is not doing anything to touch the database directly.
I am using Code First appraoch in my MVC project. Just for simplicity I have got two classes Course and Modules where there is a many to many relationship between the entities. Here is the structure of my classes
public class Course
{
public int CourseId { get; set; }
public string Title { get; set; }
public virtual ICollection<Module> Modules { get; set;
}
public class Module
{
public int ModuleId { get; set; }
public string Title { get; set; }
public int Credits { get; set; }
public virtual ICollection<Course> Courses {get;set;
}
I created two controllers for each using EntityFramework where each controller creates the table for each class. Now having the many to many relationship the EF is smart enough to create the third junction table for me ie. CourseModule(FK_Course_ID, FK_ModuleID). But the problem is this table is not get populated with the keys from the respective tables. It is blank. Can anyone please help me how can I figure it out??
Thanks.
I am going out on a limb here but do you have the following in your
context class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Course>()
.HasMany(s => s.Modules)
.WithMany(a => a.Courses)
.Map(m =>
{
m.MapLeftKey("CourseID");
m.MapRightKey("ModuleID");
m.ToTable("CourseModules");
});
}
Also, can we see your code where you try to save Course / Module?
I was thinking that the purpose of EF DataMigrations is to preserve old data while changing the database structure. Do I think right? But when I update the database with migrations all the old data is erased.
Do I make something wrong or maybe it isn't possible to use data migrations in this kind of scenario ?
this is DbContext:
public class CodeFirstContext : DbContext
{
public CodeFirstContext() : base ("ZenRandevuIzle")
{
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Takvim> Takvims { get; set; }
public DbSet<Musteri> Musteris { get; set; }
public DbSet<Randevu> Randevus { get; set; }
public DbSet<SeansTuru> SeansTurus { get; set; }
public DbSet<Hizmet> Hizmets { get; set; }
public DbSet<Islem> Islems { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
}
this is Global.asax:
Database.SetInitializer<CodeFirstContext>(new CodeFirstContextInit());
this is migration Config:
internal sealed class Configuration : DbMigrationsConfiguration<CodeFirstContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
}
Does the CodeFirstContextInit initialiser drop the database and recreate it (what is its base class?) normally I wouldn't have an initializer when using migrations.
To use EF 4.3 Code First Data Migrations with an existing database you need to create an "empty" migration so that the Migration-History table is created and a baseline can be established.
The Steps outlined in this post should help http://thedatafarm.com/data-access/using-ef-4-3-code-first-migrations-with-an-existing-database