Entity Framework Code First Seeding Data - c#

I am using code first Approach in entity framework, but I am unable to seed the default data into the table. Please help.
Models
public class Employee
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public int Salary { get; set; }
public virtual Department Departments { get; set; }
}
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public string Location { get; set; }
public virtual ICollection<Employee> Employees { get; set; }
public Department()
{
this.Employees = new List<Employee>();
}
}
Initializer
public class DepartmentInitializer : DropCreateDatabaseIfModelChanges<EmployeeDBContext>
{
protected override void Seed(EmployeeDBContext context)
{
IList<Department> lst = new List<Department>
{
new Department
{
Name = "Developer",
Location = "Bangalore"
},
new Department
{
Name = "Tester",
Location = "Bangalore"
},
new Department
{
Name = "IT Services",
Location = "Chennai"
}
};
foreach (var item in lst)
{
context.Departments.Add(item);
}
context.SaveChanges();
}
}
Main App
class Program
{
static void Main(string[] args)
{
using (var db = new EmployeeDBContext())
{
Database.SetInitializer<EmployeeDBContext>(new DepartmentInitializer());
}
}
}

For version 6 of Entity Framework, using 'migrations' is the preferred way to version the database, using the "Configuration.Seed" method as shown in this tutorial:
http://www.asp.net/web-api/overview/data/using-web-api-with-entity-framework/part-3
Have you tried running "Update-Database" from the Package Manager Console to get it to work?
I know I have had issues using the older seeding method with EF6. Migrations has also changed for Entity Framework Core 1 (formerly EF7), so make sure you are applying the correct technique to the correct version.

Try actually querying your db
On my machine, the seeder runs when I query it for the first time.
using (var db = new EmployeeDBContext())
{
Database.SetInitializer<EmployeeDBContext>(new DepartmentInitializer());
var depts = db.Departments.ToList();
}

Related

How to set up JSON columns with Npgsql?

I'm setting up a mini model and I'm getting this exception when executing the code from the docs website.
Here's my code:
public class SomeEntity
{
public int Id { get; set; }
[Column(TypeName = "jsonb")]
public Customer Customer { get; set; }
}
public class Customer // Mapped to a JSON column in the table
{
public string Name { get; set; }
public int Age { get; set; }
public Order[] Orders { get; set; }
}
public class Order // Part of the JSON column
{
public decimal Price { get; set; }
public string ShippingAddress { get; set; }
}
using (var dbContext = services.GetRequiredService<AppDbContext>())
{
await dbContext.Database.MigrateAsync();
dbContext.SomeEntities.Add(
new SomeEntity
{
Customer = new Customer
{
Name = "Roji",
Age = 35,
Orders = new[]
{
new Order { Price = 3, ShippingAddress = "Somewhere" },
new Order { Price = 3, ShippingAddress = "Nowhere" }
}
}
});
await dbContext.SaveChangesAsync();
}
When I call SaveChanges, I get the following exception:
Npgsql.PostgresException:
42P01: relation \"SomeEntities\" does not exist
Here's a repro project.
Since I believe I followed all the steps in the manual, I've opened an issue here too.
You're calling the MigrateAsync method, but your project doesn't have any actual migrations (those can be created with dotnet ef migrations add <name>). If you're just playing around, you likely want to call dbContext.Database.EnsureCreated instead, see this doc page.

Entity Framework, randomly creating duplicate records

I have a simple entity framework 6 code first from existing database project for my web application. When I save data sometimes it saves properly with only 1 record saved. However sometimes it saves 2, 3 5 records it appears random.
For simplicity sake I have the following 2 classes. One is a parent "Person", and "PersonAddress" is the child. In my application there will always be 2 child records to 1 parent. No more no less (dont ask why). Here are my classes which are bare bones.
[Table("Person")]
public partial class Person
{
[Key]
public int PersonID { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
[Required]
public virtual ICollection<PersonAddress> PersonAddresses { get; set; }
}
[Table("PersonAddress")]
public partial class PersonAddress
{
[Key]
public int PersonAddressID { get; set; }
public int PersonID { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
}
Here is my DBContext class
public partial class MyDBContext : DbContext
{
public MyDBContext()
: base("name=MyDBContext")
{
//skips database initialization so it wont track changes and produce error, not needed for code first
Database.SetInitializer<MyDBContext>(null);
}
public virtual DbSet<Person> Persons { get; set; }
public virtual DbSet<PersonAddress> PersonAddresses { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Person>().Property(x => x.PersonID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<PersonAddress>().Property(x => x.PersonAddressID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
}
}
//sample code
Person person = new Person();
person.FirstName = "TestFName";
person.LastName = "TestLName";
List<PersonAddress> addresses = new List<PersonAddress>();
PersonAddress address1 = new PersonAddress();
address1.Address1 = "line1"
//etc
//etc
addresses.Add(address1);
PersonAddress address2 = new PersonAddress();
address1.Address2 = "line1"
//etc
//etc
addresses.Add(address2);
//now add addresses to Person
person.PersonAddresses = addresses;
using (var context = new MyDBContext())
{
context.Persons.Add(person);
context.SaveChanges();
obj.PersonID = obj.PersonID;
}
What am I doing wrong, the data always gets saved and the child records are automatically added when I save the parent without issue. But as previously stated sometimes numerous sets of records are saved and I dont see any reason why. Thanks
Try this:
using (var context = new MyDBContext())
{
Person.PersonAdresses.add(addres1);
Person.PersonAdresses.add(addres2);
context.Entry(Person).State=EntityState.Added;
context.SaveChanges();
};

How to use DbRef in LiteDB

How to use DbRef in LiteDB. I have classes for both Customer and Job. I want the Customer to store a list of jobs that the Customer has.
So in the Customer class, I need to have aDbRef<Job> Jobs from what I understand. I have several issues. First, DbRef is not recognized as a type with using LiteDB. Second, I have no idea how to implement it
Job.cs
namespace HMDCompare.Classes
{
public class Job
{
public int id { get; set; }
public string name { get; set; }
}
}
Customer.cs
using LiteDB;
namespace HMDCompare.Classes
{
public class Customer
{
[BsonId]
public int Id { get; set; }
public string Name { get; set; }
public string[] Phones { get; set; }
public bool IsActive { get; set; }
public DbRef<Job> Jobs { get; set; }
}
}
for the DbRef I get in Visual Studio: The type or Namespace name 'DbRef' could not be found.
I am developing in C#/ASP.net 4.5 and with LiteDB 2.0.0-rc
Using LiteDB.2.0.0-rc and following the example in test page, worked fine for me.
public IncludeDatabase() : base("mydb.db")
{
}
public LiteCollection<Folder> Folders { get { return this.GetCollection<Folder>("Folders"); } }
public LiteCollection<SubFolders> SubFolders { get { return this.GetCollection<Media>("SubFolders"); } }
protected override void OnModelCreating(BsonMapper mapper)
{
mapper.Entity<SubFolder>()
.DbRef(x => x.Folder, "Folders");
}
.....
add
var subFolder = new SubFolder()
{
Name = file.Name,
Folder = new Folder { Id = idFolder },
};
using (var db = new IncludeDatabase())
{
db.SubFolders.Insert(subFolder);
}
get
using (var db = new IncludeDatabase())
{
return db.SubFolders
.Include(x => x.Folder)
.FindAll().ToList();
}

Entity framework returns entity which doesn't exist in database

I got a very strange behavior with EF6. I have an entity which insertion failed, but when i enumerate the entities, the first time after that, I retrieve the entity
static async Task Debug()
{
MyDbContext ctx = new MyDbContext();
Category category = new Category()
{
Name = "TEST INSERTION FAILED",
Reference = "KKK",
TranslationCategories = new List<TranslationCategory>()
{
new TranslationCategory()
{
//LangId = "FR", Force insertion failed
Name= "FR translation"
}
}
};
try
{
ctx.Categories.Add(category);
await ctx.SaveChangesAsync();
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
// throw exception because "LangId" missing in Translation Category
}
MyDbContext ctx2 = new MyDbContext();
foreach(var o in ctx2.Categories.ToList())
{
Console.WriteLine(o.Name);
//output : "TEST INSERTION FAILED" + categories stored in DB
// Why category "TEST INSERTION FAILED" in ctx2.Categories ?
}
Console.WriteLine("****************");
foreach (var o in ctx2.Categories.ToList())
{
Console.WriteLine(o.Name);
// ouput : only categories stored in DB
}
}
Category entity generated by entity framework power tools
public partial class Category
{
public Category()
{
this.Products = new List<Product>();
this.TranslationCategories = new List<TranslationCategory>();
}
public int CategoryId { get; set; }
public Nullable<int> ParentCategoryId { get; set; }
public string Reference { get; set; }
public System.DateTime CreationDate { get; set; }
public string Name { get; set; }
public Nullable<bool> Published { get; set; }
public string Artwork { get; set; }
public string TypeCode { get; set; }
public virtual ICollection<Product> Products { get; set; }
public virtual ICollection<TranslationCategory> TranslationCategories {get;set; }
}
I solved my problem. My entities and DBContext was generated using "entity framework power tools, reverse engineer code first".
I have regenerated entities and dbcontext by adding Ado.net data entity model, Code First from Existing Database, and now the same code works.

Saving an entity graph using entity framework

I am writing a Data Access Layer using EntityFramework 6. What I want is that when I invoke the SaveChanges() method on the DbContext, it will save the entity together with the set of relevant entities associated via navigation properties. Following is the simple code I am trying to do.
public class Customer
{
public long ID { get; set; }
public string Name { get; set; }
public virtual IEnumberable<PhoneNumber> { get; set; }
}
public class PhoneNumber
{
public long ID { get; set; }
public string Number { get; set; }
}
public class SampleContext : DbContext
{
public virtual DbSet<Customer> Customers { get; set; }
public virtual DbSet<PhoneNumber> PhoneNumbers { get; set; }
}
using(var context = new SampleContext())
{
var customer = new Customer { ID = 1, Name = "John" };
customer.PhoneNumbers = new PhoneNumbers[]
{
new PhoneNumber { ID = 1, Number = "1.111.1111111" },
new PhoneNumber { ID = 2, Number = "1.111.1111112" }
}
context.Customers.Add(customer);
context.SaveChanges();
}
The above code saves the customer in the customers table but saves nothing in the PhoneNumbers table.
Strange but found a solution. The above code need a little modification to make it work. Followings are the modifications:
//In Customer class, changed following line:
public virtual IEnumberable<PhoneNumber> { get; set; }
//To:
public virtual ICollection<PhoneNumber> { get; set; }
//Then in using block initialized entities as follows:
using(var context = new SampleContext())
{
var customer = new Customer { ID = 1, Name = "John", PhoneNumbers = new List<PhoneNumber>() };
customer.PhoneNumbers.Add(new PhoneNumber { ID = 1, Number = "1.111.1111111" });
context.Customers.Add(customer);
context.SaveChanges();
}

Categories