I've problem with seeding data to database. Eariler I tried way from this tut: Seed Data in EF 6 Code-First
and then the seed method is never called
DBSchool.cs
namespace SchoolTest.DAL
{
public class DBSchool : DbContext
{
public DBSchool() : base("DBSchool")
{
Database.SetInitializer(new Seeder());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public DbSet<Guest> Guests { get; set; }
}
}
Seeder.cs
public class Seeder : DropCreateDatabaseAlways<DBSchool>
{
protected override void Seed(DBSchool context)
{
IList<Guest> GuestList = new List<Guest>();
GuestList.Add(new Guest()
{
Name = "Dexter",
Surname = "Dexter",
Email = "test#test.com"
});
context.Guests.AddRange(GuestList);
context.SaveChanges();
base.Seed(context);
}
}
Guest.cs
public class Guest
{
public string Name { get; set; }
public string Surname { get; set; }
public string Email { get; set; }
[Key]
public int GuestId { get; set; }
}
App.config
<appSettings>
<add key="DatabaseInitializerForType SchoolTest.DAL.DBSchool, SchoolTest"
value="SchoolTest.Data.Seeder, SchoolTest" />
</appSettings>
Is there any way to call the Seed() method or just through the Configuration.cs?
Try changing your code like this.
public class DBSchool : DbContext
{
public DBSchool() : base("name=<database-name>")
{
Database.SetInitializer<DBSchool>(new Seeder());
}
// Rest of your implementation
}
Replace <database-name> with the name of your database.
If that didn't work, you can give a Generic Type Parameter to the context class and change your code as follows.
Seeder.cs -> public class Seeder<T> : DropCreateDatabaseAlways<DBSchool>
DBSchool.cs -> Database.SetInitializer<DBSchool>(new Seeder<DBSchool>());
Read more on that here.
If that didn't work either, you can use migrations and seed data using custom sql using Sql().
Related
when i want to add fields in the database it tells me "SQLite Error 1: 'no such table: Players'." but as soon as i look at my database there is a players table. how can i solve this problem?
Here are the files for saving in the DB
GameDbContext
namespace MereTuBois.Data
{
public class GameDbContext : DbContext
{
private readonly IDeviceService _deviceService;
public DbSet<Players> Players { get; set; }
public DbSet<Session> Sessions { get; set; }
public GameDbContext(IDeviceService deviceService)
{
_deviceService = deviceService;
//this.Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
string dbPath = Path.Combine(_deviceService?.AppDataDirectory ?? ".", "mereTubois.db3");
optionsBuilder.UseSqlite($"Filename={dbPath}");
}
}
public class HistoryContextFacotry : IDesignTimeDbContextFactory<GameDbContext>
{
public GameDbContext CreateDbContext(string[] args)
{
return new GameDbContext(null);
}
}
}
link to the migration : https://github.com/Waterlok653/MIgration
to solve the problem I have removed the following comment : this.Database.EnsureCreated();
Im learning Postgresql with EF Core 2.0
im keep getting this error. I searched on google but but I am not able to find the right answer.
Here is some detail of my code ;
Startup.CS;
public void ConfigureServices(IServiceCollection services)
{
var connectionString = #"User ID=postgres;Password=postgres;Host=localhost;Port=5432;Database=Test;";
services.AddEntityFrameworkNpgsql()
.AddDbContext<DataContext>(options => options.UseNpgsql(connectionString));
services.AddMvc();
}
and Data Context ;
public class DataContext : DbContext
{
public DataContext(DbContextOptions<DataContext> options) : base(options)
{
}
public DbSet<Questions> Questions { get; set; }
}
and my model ;
public class Questions
{
public int Id { get; set; }
public int studentId { get; set; }
public string Title { get; set; }
public int Votes { get; set; }
}
any help would be appreciated.
Stumbled across this question and, although late to the party, I've also experienced case sensitivity with Oracle (using Oracle.EntityFrameworkCore, where I needed uppercase) and postgres (using Npgsql.EntityFrameworkCore, where I needed lowercase) for table/column names.
I'll add my resolution here so that it helps anyone else in future. I resolved by creating an extension method as follows:
public static void LowercaseRelationalTableAndPropertyNames(this ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
entity.Relational().TableName = entity.Relational().TableName.ToLowerInvariant();
foreach (var property in entity.GetProperties())
{
property.Relational().ColumnName = property.Relational().ColumnName.ToLowerInvariant();
}
}
}
and using as follows:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.LowercaseRelationalTableAndPropertyNames();
}
which allows models to be built with mixed case and converted at runtime as follows:
public class Questions
{
public int Id { get; set; }
public int StudentId { get; set; }
}
Note, for EFCore 3.0, the extension method changes as follows:
public static void LowercaseRelationalTableAndPropertyNames(this ModelBuilder modelBuilder)
{
foreach (var entity in modelBuilder.Model.GetEntityTypes())
{
entity.SetTableName(entity.GetTableName().ToLowerInvariant());
foreach (var property in entity.GetProperties())
{
property.SetColumnName(property.GetColumnName().ToLowerInvariant());
}
}
}
Alright fixed.
i think postgresql is case sensetive.
when i changed model equal to database problem is solved.
here is my new model.
I have following code first model:
public class Model1 : DbContext
{
public Model1()
: base("name=Model1")
{
}
public virtual DbSet<Master> Masters { get; set; }
public virtual DbSet<Slave> Slaves { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Master>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Slave>().Property(e => e.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
modelBuilder.Entity<Master>().Property(e => e.Name).IsRequired();
modelBuilder.Entity<Slave>().Property(e => e.Name).IsRequired();
}
}
public interface IEntity
{
int Id { get; }
}
public class Master : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Slave> Slaves { get; set; }
public Master()
{
Slaves = new EntityHashSet<Slave>();
}
public Master(string name)
: this()
{
Id = name.GetHashCode();
Name = name;
}
public void Update(IEnumerable<Slave> slaves, Model1 model)
{
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
}
public void Update(IEnumerable<string> slaves, Model1 model)
{
Update(slaves.Select(s => new Slave(s)), model);
}
}
public class Slave : IEntity
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Master> Masters { get; set; }
public Slave()
{
Masters = new EntityHashSet<Master>();
}
public Slave(string name)
: this()
{
Id = name.GetHashCode();
Name = name;
}
}
I'm using the following utility classes:
public class EntityHashSet<TEntity> : HashSet<TEntity> where TEntity : IEntity
{
public EntityHashSet()
: base(new EntityEqualityComparer<TEntity>())
{ }
public EntityHashSet(IEnumerable<TEntity> collection)
: base(collection, new EntityEqualityComparer<TEntity>())
{ }
}
public class EntityEqualityComparer<TEntity> : IEqualityComparer<TEntity> where TEntity : IEntity
{
public bool Equals(TEntity x, TEntity y)
{
return x.Id.Equals(y.Id);
}
public int GetHashCode(TEntity obj)
{
return obj.Id.GetHashCode();
}
}
public static class ExtensionMethods
{
public static TEntity CreateOrFind<TEntity>(this DbSet<TEntity> dbSet, TEntity entity) where TEntity : class, IEntity
{
return dbSet.Find(entity.Id) ?? dbSet.Add(entity);
}
}
When I first add master entity to the database with the following code no error is thrown:
using (var model = new Model1())
{
var m = new Master("master1");
m.Update(new[] {"slave1", "slave2", "slave3"}, model);
model.Masters.Add(m);
model.SaveChanges();
}
When I try to use the update method for existing one, DbUpdateException is thrown:
var m = model.Masters.CreateOrFind(new Master("master1"));
m.Update(new[] {"slave1", "slave2", "slave3", "slave4"}, model);
model.SaveChanges();
Additional information: An error occurred while saving entities that do not expose foreign key properties for their relationships. The EntityEntries property will return null because a single entity cannot be identified as the source of the exception. Handling of exceptions while saving can be made easier by exposing foreign key properties in your entity types. See the InnerException for details.
Relevant inner exception:
Violation of PRIMARY KEY constraint 'PK_dbo.SlaveMasters'. Cannot insert duplicate key in object 'dbo.SlaveMasters'. The duplicate key value is (1928309069, -2136434452).
The statement has been terminated.
Why is this? I'm checking whether entities are already in the database or need to be created via CreateOrFind.
EDIT: To clarify, the line that produces the error is:
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
Error is thrown when calling SaveChanges().
I postpone you must be use the previous ef config file ,so it will always try to insert the same value but update .
you could update or check your ef config file before update.
Found a dirty way of getting around this. Before I create new EntityHashSet I call raw SQL command deleting entries from SlaveMasters table that contains current master Id.
model.ExecuteSqlCommand("DELETE FROM SlaveMasters WHERE Master_Id = " + Id);
Slaves = new EntityHashSet<Slave>(slaves.Select(s => model.Slaves.CreateOrFind(s)));
I have a DbContext like this,
public class EPDContext : TrackerContext
{
public EPDContext()
: base("name=DevelopmentApplicationServices")
{
Database.SetInitializer<EPDContext>(new EPDDBInitializer());
this.Database.Log = s => System.Diagnostics.Debug.WriteLine(s);
}
public DbSet<TaskRevision> TaskRevisions { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TaskRevision>().HasMany(x => x.Models).WithMany().Map(x => x.MapLeftKey("TaskRevisionID").MapRightKey("ModelId").ToTable("TaskRevision2Models"));
}
}
public class EPDDBInitializer : CreateDatabaseIfNotExists<EPDContext>
{
protected override void Seed(EPDContext context)
{
//// My Seeding data goes here
base.Seed(context);
}
}
And my Entity:
[TrackChanges]
public class TaskRevision
{
#region properties
[Key]
public Guid TaskRevisionID { get; set; }
public virtual List<Model> Models { get; set; }
}
and my migration configuration class looks like:
internal sealed class Configuration : DbMigrationsConfiguration<PW.EPD.Data.EPDContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
}
protected override void Seed(PW.EPD.Data.EPDContext context)
{
}
}
I got this error "There is already an object named 'TaskRevisions' in the database entity framework." when I execute my application. DB has created successfully and there is no seeding data.
At the same time when I execute the same code after removing the onModelCreating() override method, db has created with seed data.
What I did wrong here, kindly correct me.
Thanks in advance
I'm making a DataService with Entity Framework 4.1 using Code First POCO objects. I can access the data fine when I create an instance of MyEntityContext and access it directly, however when I try and access the DataService over HTTP it breaks with the following error:
System.ArgumentException: The given name 'Department' was not found in the entity sets.
I've tried all sorts of things but keep coming back to the same problem. Not sure what could be wrong.
Department is the only Entity I am mapping currently. It is defined as follows:
[Table("tb_department")]
public class Department
{
[Key]
[Column("department_no", TypeName = "nvarchar")]
public string ID { get; set; }
[Column("department_name", TypeName = "nvarchar")]
public string Name { get; set; }
}
My data context looks like this:
public class MyEntityContext : DbContext
{
public MyEntityContext(string connStr)
: base(connStr)
{
}
public MyEntityContext()
{
}
public DbSet<Department> Departments { get; set; }
}
And my service looks like this:
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]
public class MyDataService : DataService<MyEntityContext>
{
public static void InitializeService(DataServiceConfiguration config)
{
config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
config.UseVerboseErrors = true;
config.SetEntitySetAccessRule("Department", EntitySetRights.AllRead);
}
protected override MyEntityContext CreateDataSource()
{
MyEntityContext ctx = new MyEntityContext(
Utility.GenerateConnStr
);
return ctx;
}
}
Well it says "Department" was not found in the entity sets and your entity set name is "Departments" so try pluralizing the call.