Can't get Seeding to Work EF Code First - asp.net-mvc

I have a couple of related entities and I am trying to seed the database with some dummy data. Here is my seed code:
public class EventInitializer : DropCreateDatabaseAlways<BSContext>
{
protected override void Seed(BSContext context)
{
var authors = new List<Author>
{
new Author { Name = "Christina Gabbitas" },
new Author { Name = "Gemma King" },
new Author { Name = "Gemma Collins"},
new Author { Name = "Billy Hayes" },
new Author { Name = "Jodi Picoult" },
new Author { Name = "John Whaite" }
};
authors.ForEach(a => context.Authors.Add(a));
context.SaveChanges();
var events = new List<Event>
{
new Event { Authors = new List<Author> { context.Authors.Find(0) }, Book = "Felicity Fly", Info = "Christina Gabbitas will be signing copies of her new book, Felicity Fly. Books should be bought from WHSmith. Proof of purchase may be necessary", Start = new DateTime(2013, 05, 25, 10, 30, 00), Url = "http://www.whsmith.co.uk/Support/InStoreSignings.aspx", Location = new Location { Name = "WHSmith Brent Cross", Address = "Brent Cross Shopping Centre", City = "London", County = "", PostCode = "NW4 3FB", Telephone = 02082024226 } },
new Event { Authors = new List<Author> { context.Authors.Find(1) }, Book = "Haunted Spalding", Info = "Gemma King will be signing copies of her new book. Books should be bought from WHSmith. Proof of purchase may be necessary", Start = new DateTime(2013, 03, 31, 10, 00, 00), Url = "http://www.whsmith.co.uk/Support/InStoreSignings.aspx", Location = new Location { Name = "WHSmith Spalding", Address = "6-7 Hall Place", City = "Spalding", County = "Lincolnshire", PostCode = "PE11 1SA", Telephone = 01775768666 } },
new Event { Authors = new List<Author> { context.Authors.Find(3) }, Book = "Midnight Express", Info = "Billy Hayes will be signing copies of his books. Books should be bought from WHSmith. Proof of purchase may be necessary", Start = new DateTime(2013, 04, 13, 13, 00, 00), Url = "http://www.whsmith.co.uk/Support/InStoreSignings.aspx", Location = new Location { Name = "WHSmith Birmingham", Address = "29 Union Street", City = "Birmingham", County = "West Midlands", PostCode = "B2 4LR", Telephone = 01216313303 } }
};
events.ForEach(e => context.Events.Add(e));
context.SaveChanges();
}
}
The seed code above sits in a separate project along with all my entities. I did this to keep my domain model totally separate from my web application. Of course I have references in my controllers to access the entities.
I've used EF Code First before, but this time it isn't working for me! When I go to access the data like so in my controller (ASP.NET MVC application), I get 0 results.
public ActionResult Index()
{
ViewBag.Message = "Move around the map to find events near you.";
var model = new IndexVM();
using(var context = new BSContext())
{
model.Events = (List<Event>)context.Events.ToList();
}
return View(model);
}
I am using EF (v4.0.30319) on Windows 8 64x Pro with Visual Studio 2012. To make matters worse, I can't even debug! My breakpoint is never hit when I try to run in debug mode! Here is my Web.config for the web project.

You need to call Database.SetInitializer like this:
Database.SetInitializer<BSContext>( new EventInitializer() );

Related

The conflict occurred in database "X", table "dbo.Y", column 'ld'

I'm trying to get a certain amount of animals that have the most comments once I try to delete one of them so I'm getting an error of:
SqlException: The DELETE statement conflicted with the REFERENCE constraint "FK__Comments__Animal__2EDAF651". The conflict occurred in database "PetShop", table "dbo.Comments", column 'AnimalId'. The statement has been terminated.
I want to make it possible that if I delete then you will move on to the next in line
My Controller for disply:
public async Task<IActionResult> Index()
{
var animal = _context.Animals.Include(c => c.Comments).OrderByDescending(c => c.Comments.Count).Take(2);
return View(await animal.ToListAsync());
}
My Controller for Delete:
public async Task<Animal> DeleteAnimal(int id)
{
var comment = await _context.Comments.FindAsync(id);
_context.Comments.Remove(comment!);
var animal = await _context.Animals.FindAsync(id);
_context.Animals.Remove(animal!);
await _context.SaveChangesAsync();
return animal!;
}
My Context:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Comment>(entity =>
{
entity.HasOne(d => d.Animal)
.WithMany(p => p.Comments)
.HasForeignKey(d => d.AnimalId)
.OnDelete(DeleteBehavior.ClientSetNull)
.HasConstraintName("FK__Comments__Animal__2EDAF651");
});
modelBuilder.Entity<Category>(entity =>
entity.HasData(
new { CategoryId = 1, Name = "Dogs" },
new { CategoryId = 2, Name = "Cats" },
new { CategoryId = 3, Name = "Birds" },
new { CategoryId = 4, Name = "Rabbits" },
new { CategoryId = 5, Name = "Hamsters" }
)
);
modelBuilder.Entity<Animal>(entity =>
{
entity.HasData(
new { AnimalId = 1, Name = "Shoko", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-1).AddDays(-12), Description = "Friendly and loyal", CategoryId = 1, PhotoUrl = "ShokoDog.jpg" },
new { AnimalId = 2, Name = "Bamba", BirthDate = DateTime.Now.AddYears(-2).AddMonths(-2).AddDays(-3), Description = "Furry and neutered", CategoryId = 2, PhotoUrl = "BambaCat.jpg" },
new { AnimalId = 3, Name = "Regev", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-3).AddDays(-3), Description = "Speak", CategoryId = 3, PhotoUrl = "RegevBird.jpg" },
new { AnimalId = 4, Name = "Humi", BirthDate = DateTime.Now.AddYears(-3).AddMonths(-4).AddDays(-7), Description = "Cute and furry", CategoryId = 4, PhotoUrl = "HumiRabbit.jpg" },
new { AnimalId = 5, Name = "Tommy", BirthDate = DateTime.Now.AddYears(-1).AddMonths(-7).AddDays(-9), Description = "Love to play in the facilities", CategoryId = 5, PhotoUrl = "TommyHamster.jpg" });
});
OnModelCreatingPartial(modelBuilder);
}
You want to remove a parent Animal and related child Comments
To expand on Karlis' suggestions:
You have models and context as posted in the question (it's a bit problematic because you say to EF to set null, but the code and DB won't accept null) but you can do:
var a = context.Animals.Include(a => a.Comments).Find(id):
context.Comments.RemoveRange(a.Comments);
context.Animals.Remove(a);
context.SaveChanges();
This explicitly removes the comments then the animal
Change the context to use .OnDelete(DeleteBehavior.ClientCascade) then you can do:
var a = context.Animals.Include(a => a.Comments).Find(id):
context.Animals.Remove(a);
context.SaveChanges();
This causes EF to implicitly remove the comments it knows about when you tell it explicitly to remove the animal
Change the DB's foreign key to do an ON DELETE CASCADE, and change .OnDelete(DeleteBehavior.Cascade) then you can skip downloading the Comments (no include):
var a = context.Animals.Find(id):
context.Animals.Remove(a);
context.SaveChanges();
This causes the DB to remove the comments (EF doesn't know about them) when EF instructs to delete the animal
Broadly speaking, these are in order of "how bad of a mistake could you make" from "not very" to "quite a lot"
The error message reads that you are deleting Animal, which has comments associated. You should do one of the following:
Remove comments associated with a particular Animal before deleting the Animal.
Check EF configuration for cascade on delete
Alter FK to have cascade on delete (it depends on whether you are using a database-first or code-first approach)
I would go for the first approach because cascade on delete may be dangerous and silently remove unintentionally referenced data.

Seed Method Doesn't Populate Tables

The database is create successfully as well as the tables. However, whether I put the seed code in the configuration file or as a initializer. The tables are never populated with data.
Things I have tried:
1. I have been viewed several posts on stackoverflow comparing my code with solutions to no avail.
2. I changed DropCreateDatabaseIfModelChanges to DropCreateDatabaseAlways, still the same.
3. I have verified all required fields have a value
public class BankAccountInitializer : DropCreateDatabaseAlways<BankAccountContext>
{
protected override void Seed(BankAccountContext context)
{
var bank1 = new Bank(1) { BankName = "Huntington", BankAccounts = new List<BankAccount>() };
context.Banks.Add(bank1);
context.BankAccounts.Add
(
new CheckingAccount(1)
{
BankId = 1,
AccountBalance = 25.00m,
BankAccountName = "Checking Account 1",
DateAdded = DateTime.Now,
RoutingNumber = 00000887,
Owner = "Checking Account Owner 1",
Bank = bank1
}
);
context.BankAccounts.Add
(
new IndividualInvestment(2)
{
BankId = 1,
AccountBalance = 10.00m,
BankAccountName = "Individual Investment 1",
DateAdded = DateTime.Now,
RoutingNumber = 00000887,
Owner = "Individual Investment Owner 1",
Bank = bank1
}
);
context.BankAccounts.Add(
new CorporateInvestment(3)
{
BankId = 1,
AccountBalance = 98.00m,
BankAccountName = "Corporate Investment 1",
DateAdded = DateTime.Now,
RoutingNumber = 00000887,
Owner = "Corporate Investment Owner 1",
Bank = bank1
}
);
base.Seed(context);
}
}
}

Google calendar Add Event In ASP .net : Auth fail

In my asp.net core app I'm going to add new event to google calendar. But it showing error in google. I have enabled calendar api and insert ClientId and ClientSecret. But it showing error.
This is my code below.
and
public void CreateEvent(string email, string text)
{
UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(
new ClientSecrets
{
ClientId = "461480317556-xxxxxxxxxxg.apps.googleusercontent.com",
ClientSecret = "RljgIL79D2YFkmVaWQypCjIa",
},
new[] { CalendarService.Scope.Calendar },"user",CancellationToken.None).Result;
// Create the service.
var service = new CalendarService(new BaseClientService.Initializer()
{
HttpClientInitializer = credential,
ApplicationName = "Calendar API Sample",
});
Event myEvent = new Event
{
Summary = "Appointment",
Location = "Somewhere",
Start = new EventDateTime()
{
DateTime = new DateTime(2014, 6, 2, 10, 0, 0),
TimeZone = "America/Los_Angeles"
},
End = new EventDateTime()
{
DateTime = new DateTime(2014, 6, 2, 10, 30, 0),
TimeZone = "America/Los_Angeles"
},
Recurrence = new String[] { "RRULE:FREQ=WEEKLY;BYDAY=MO" },Attendees = new List<EventAttendee>(){new EventAttendee() { Email = email } }
};
Event recurringEvent = service.Events.Insert(myEvent, "primary").Execute();
}
I have resolved issue my self.Problem was I have put type as "Web Application" Instead of "other".. After I changed it to type as "other" It worked.

seeded data is duplicated code first migration

I have seeded the database using code first migration, however I noticed when I view the seeded data in index.html, the data is replicated.
This is the configuration file were I seeded the data:
internal sealed class Configuration : DbMigrationsConfiguration
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(OnlineBookStore.Models.OnlineBookStoreDB context)
{
var books = new System.Collections.Generic.List<Book>
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
books.ForEach(s =>context.Books.AddOrUpdate(p => new { p.ISBN, p.Title } ));
context.SaveChanges();
}
}
}
I am really unsure of were I am going wrong, spent days on this!
Really appreciate anyones help! thanks!
You need to specify the key in AddOrUpdate to prevent duplicates since Seed() runs with every update-database issued.
// build your books collection
var books = new []
{
new Book {
BookStatus = new BookStatus { Status = "New" },
Genre = new Genre { Name = "Thriller" },
Author = new Author { Name = "Paula Hawkins" },
Title = "The Girl On The Train",
Description = "Rachel catches the same commuter train morning. ",
ISBN = 0552779776,
},
new Book
{
BookStatus = new BookStatus { Status = "Best Seller" },
Genre = new Genre { Name = "Childrens" },
Author = new Author { Name = "Roald Dahl" },
Title = "The Witches",
Description = "Beware. Real witches dress in ordinary clothes",
ISBN = 0141365471,
},
},
};
context.Books.AddOrUpdate(p => new { p.ISBN, p.Title }, books);
context.SaveChanges();
See http://thedatafarm.com/data-access/take-care-with-ef-4-3-addorupdate-method/

Why isn't my database being created in ASP.NET MVC4 with EF CodeFirst

I've been following along with a tutorial by Julie Lerman about using EF CodeFirst to generate the database from code. I'm using MVC4 and working with the default controllers. All I want to do is generate the database. However, in her tutorial, she's working with a console application and calling a create_blog method in her Main function. The create_blog function does the work of creating the database as the name suggests.
In my Global.asax, I have this:
Database.SetInitializer(new CIT.Models.SampleData());
This is my SampleData class:
public class SampleData : CreateDatabaseIfNotExists<Context>
{
protected override void Seed(Context context)
{
base.Seed(context);
new List<Software> {
new Software { Title = "Adobe Creative Suite", Version = "CS6", SerialNumber = "1234634543", Platform = "Mac", Notes = "Macs rock!", PurchaseDate = "2012-12-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "Paradise" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Adobe" }}},
new Software { Title = "Apple iLife", Version = "2012", SerialNumber = "123463423453", Platform = "Mac", Notes = "Macs still rock!", PurchaseDate = "2012-11-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "81st Street" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Apple" }}},
new Software { Title = "Microsoft Office", Version = "2012", SerialNumber = "12346231434543", Platform = "PC", Notes = "Macs really rock!", PurchaseDate = "2011-12-04", Suite = true, SubscriptionEndDate = null, SeatCount = 4, SoftwareTypes = new List<SoftwareType> { new SoftwareType { Type="Suite" }}, Locations = new List<Location> { new Location { LocationName = "Paradise" }}, Publishers = new List<SoftwarePublisher> { new SoftwarePublisher { Publisher = "Microsoft" }}}
}.ForEach(s => context.Software.Add(s));
}
}
I get no errors when I compile. I just get no database. I looked in my App_Data and all that's there is the default database. I have a dbContext that is getting called because when I had errors in it, they pointed to that file. Do I need to have some kind of create method that is called when the site first compiles?
SetInitializer only sets the initializer strategy and the strategy is executed the first time you access the database. Try adding the following after calling SetInitializer
using (var context = new Context()) { context.Database.Initialize(true); }

Resources