I've used add-migration and then update-database - both run with no errors, but the changes I am requesting to happen did not happen. I check my table data in the Server Explorer and it will not add the new column along with the other new data. I've attached my code if you need more of the code please let me know.
I did create another migration and copied the same changes to be added to the new changes to see if the new one would push. Migrations/Update2.cs and Migrations/Update1.cs are the same exact code.
//Migrations/Update2.cs "The updated Migration"
namespace EnrollmentApplication.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class Update2 : DbMigration
{
public override void Up()
{
AddColumn("dbo.Courses", "InstructorName", c => c.String());
AddColumn("dbo.Enrollments", "Notes", c => c.String());
AddColumn("dbo.Students", "Age", c => c.Int(nullable: false));
AlterColumn("dbo.Courses", "CourseTitle", c => c.String(nullable: false, maxLength: 150));
AlterColumn("dbo.Courses", "CourseCredits", c => c.String(nullable: false, maxLength: 4));
AlterColumn("dbo.Enrollments", "Grade", c => c.String(nullable: false));
AlterColumn("dbo.Enrollments", "AssignedCampus", c => c.String(nullable: false));
AlterColumn("dbo.Enrollments", "EnrollmentSemester", c => c.String(nullable: false));
AlterColumn("dbo.Students", "StudentFirstName", c => c.String(nullable: false, maxLength: 50));
AlterColumn("dbo.Students", "StudentLastName", c => c.String(nullable: false, maxLength: 50));
}
public override void Down()
{
AlterColumn("dbo.Students", "StudentLastName", c => c.String());
AlterColumn("dbo.Students", "StudentFirstName", c => c.String());
AlterColumn("dbo.Enrollments", "EnrollmentSemester", c => c.String());
AlterColumn("dbo.Enrollments", "AssignedCampus", c => c.String());
AlterColumn("dbo.Enrollments", "Grade", c => c.String());
AlterColumn("dbo.Courses", "CourseCredits", c => c.String());
AlterColumn("dbo.Courses", "CourseTitle", c => c.String());
DropColumn("dbo.Students", "Age");
DropColumn("dbo.Enrollments", "Notes");
DropColumn("dbo.Courses", "InstructorName");
}
}
}
//Models/Course.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace EnrollmentApplication.Models
{
public class Course : IValidatableObject
{
public virtual int CourseId { get; set; }
[Required,]
[StringLength(150)]
public virtual string CourseTitle { get; set; }
public virtual string CourseDescription { get; set; }
[Required]
[StringLength(4), MinLength(1)]
public virtual string CourseCredits { get; set; }
public virtual string InstructorName { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
// Validation 1: Credits have to be between 1-4
if(CourseDescription.Split (' ').Length > 100)
{
yield return (new ValidationResult("Your description is too verbose"));
}
throw new NotImplementedException();
}
}
}
//Models/Enrollment.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace EnrollmentApplication.Models
{
public class Enrollment
{
public virtual int EnrollmentId { get; set; }
public virtual int StudentId { get; set; }
public virtual int CourseId { get; set; }
[Required]
[RegularExpression("[A-F])")]
public virtual string Grade { get; set; }
public virtual Student Student { get; set; }
public virtual Course Course { get; set; }
public virtual bool IsActive { get; set; }
[Required]
public virtual int AssignedCampus { get; set; }
[Required]
public virtual string EnrollmentSemester { get; set; }
[Required]
public virtual int EnrollmentYear { get; set; }
[RegularExpression(#"^[0-9a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Invalid Characters")]
public virtual string Notes { get; set; }
}
}
//Models/Student.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
namespace EnrollmentApplication.Models
{
public class Student
{
public virtual int StudentID { get; set; }
[Required]
[StringLength(50)]
public virtual string StudentFirstName { get; set; }
[Required]
[StringLength(50)]
public virtual string StudentLastName { get; set; }
//MinimumAge(20)
[MinimumAge(20)]
public virtual int Age { get; set; }
public virtual string Address1 { get; set; }
public virtual string Address2 { get; set; }
public virtual string City { get; set; }
[MaxLength(5)]
[MinLength(5)]
[RegularExpression(#"^[0-9a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Enter a 5 digit zipcode")]
public virtual string Zipcode { get; set; }
[MaxLength(2)]
[MinLength(2)]
[RegularExpression(#"^[0-9a-zA-Z''-'\s]{1,40}$",
ErrorMessage = "Enter a 2 digit State code")]
public virtual string State { get; set; }
}
}
There's zero error messages but my changes are not applied.
I had to Delete the Migrations folder, Delete the database in the Server Explorer, and in the Windows Explorer, delete my database in the App Data folder. Reloaded the application and built the new database and everything went through properly.
Related
This is my simplified schema.
I want to add a contact who is a custodian and attach them to an existing facility. The ContactType just states what type of contact the record is such as a company or individual. In this case the custodian is an individual.
I can insert a contact by itself just fine.
The complication for me is because of the many to many and one to many relationships.
In the controller I have
vm.Contact.Facilities.Add(new Facility { FacilityID = vm.SelectedFacilityID });
_repo.SaveContact(vm);
In the repo
_db.Contacts.Add(vm.Contact);
_db.SaveChanges();
This gives me a foreign key error since it tries to insert a new facility and I have other foreign keys in that table not shown. I don't want to add a facility but just reference the FacilityID.
Convention is to Not explicitly try to insert a record in the many to many, FacilityCustodian table directly by doing something like this
var fc = new FacilityCustodian { CustodianFacilityID = vm.SelectedFacilityID };
vm.Contact.FacilityCustodian.Add(fc);
I also tried
foreach (var facility in vm.Contact.Facilities)
{
_db.Entry(facility).State = EntityState.Unchanged;
}
Most of the examples I have seen don't have both relationships so I'm not sure how to proceed.
Thanks for any help.
ADDED CODE
using Licensing.Models;
namespace Licensing
{
using System.Data.Entity;
public class Context : DbContext
{
public Context()
: base("name=Context")
{
}
public virtual DbSet<Contact> Contacts { get; set; }
public virtual DbSet<ContactType> ContactTypes { get; set; }
public virtual DbSet<Facility> Facilities { get; set; }
public virtual DbSet<FacilityCandler> FacilityCustodians { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Contact>()
.Property(e => e.FName)
.IsUnicode(false);
modelBuilder.Entity<Contact>()
.Property(e => e.LName)
.IsUnicode(false);
modelBuilder.Entity<Contact>()
.HasMany(e => e.Facilities)
.WithRequired(e => e.Contact)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Contact>()
.HasMany(e => e.FacilityCustodians)
.WithRequired(e => e.Contact)
.HasForeignKey(e => e.CustodianFacilityID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<ContactType>()
.Property(e => e.Type)
.IsUnicode(false);
modelBuilder.Entity<ContactType>()
.HasMany(e => e.Contacts)
.WithRequired(e => e.ContactType)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Facility>()
.HasMany(e => e.FacilityCustodians)
.WithRequired(e => e.Facility)
.HasForeignKey(e => e.CustodianFacilityID)
.WillCascadeOnDelete(false);
}
}
}
namespace Licensing.Models
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Spatial;
[Table("Contact")]
public class Contact
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Contact()
{
Facilities = new HashSet<Facility>();
FacilityCustodians = new HashSet<FacilityCustodian>();
}
[Key]
public int ContactID { get; set; }
public int ContactTypeID { get; set; }
[Display(Name = "First Name")]
[RegularExpression(#"^[a-zA-Z'.\s]+$", ErrorMessage = "Enter a valid Name")]
[StringLength(150)]
public string FName { get; set; }
[Display(Name = "Last Name")]
[RegularExpression(#"^[a-zA-Z'\s]+$", ErrorMessage = "Enter a valid Name")]
[StringLength(150)]
public string LName { get; set; }
public virtual ContactType ContactType { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Facility> Facilities { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<FacilityCustodian> FacilityCustodians { get; set; }
}
}
using System.ComponentModel.DataAnnotations;
namespace Licensing.Models
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
[Table("Facility")]
public class Facility
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Facility()
{
FacilityCustodians = new HashSet<FacilityCustodian>();
}
[Key]
public int FacilityID { get; set; }
public int ContactID { get; set; }
public virtual Contact Contact { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<FacilityCustodian> FacilityCustodians { get; set; }
}
}
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Licensing.Models
{
[Table("FacilityCustodian")]
public partial class FacilityCustodian
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CustodianFacilityID { get; set; }
[Key]
[Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int CustodianContactID { get; set; }
public virtual Contact Contact { get; set; }
public virtual Facility Facility { get; set; }
}
}
namespace Licensing.Models
{
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Table("ContactType")]
public class ContactType
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ContactType()
{
Contacts = new HashSet<Contact>();
}
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int ContactTypeID { get; set; }
[Required]
[StringLength(10)]
public string Type { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Contact> Contacts { get; set; }
}
}
UPDATE Working Code
var existingFacility = _repo.GetFacilityByFacilityID(vm.SelectedFacilityID);
vm.Contact.LName = vm.LName;
vm.Contact.FName = vm.FName;
vm.Contact.Name = vm.FName + " " + vm.LName;
vm.Contact.ContactTypeID = 1;
vm.Contact.FacilityCustodians.Add(existingFacility);
_db.Contacts.Add(vm.Contact);
_db.SaveChanges();
Try this Since I dont have complete folder I tried to simplify the model all classes are name mentioned in diagram but I create. Below are my model classes . The import thing to note is that read the entoty from contecxt first and then updated the values and set entitystate accordingly . This will solve your issue .
Model classes :-
public class ContactType
{
public int ContactTypeId { get; set; }
public string Name { get; set; }
}
public class Contact
{
public int ContactId { get; set; }
public string Name { get; set; }
public int ContactTypeId { get; set; }
[ForeignKey("ContactTypeId")]
public virtual ContactType ContactType { get; set; }
public virtual ICollection<Facility> Facilities { get; set; }
}
public class FacilityCustodian
{
public int FacilityId { get; set; }
public int ContactTypeId { get; set; }
[ForeignKey("ContactId")]
public virtual Contact Contact { get; set; }
[ForeignKey("FacilityId")]
public virtual
Facility Facility { get; set; }
}
public class Facility
{
public int FacilityId { get; set; }
public string Location { get; set; }
public int ContactId { get; set; }
[ForeignKey("ContactId")]
public virtual Contact Contact { get; set; }
public virtual ICollection<Contact> Contacts { get; set; }
}
-- here I am showing you to update existing contact and add a new facility to it . same as you case you want to update facility ...
using (var ctx = new SampleDbContext())
{
//this is important to read the entity first .
var contact = ctx.Contacts.FirstOrDefault(x=>x.ContactId ==vm.Contact.ContactId);
if (contact != null)
{
// Since facilityId is a primary key I set it to autoincrement so I dont have to set it .You can set if it is not primarykey
contact.Name = "Updated";
// update the entity and add new information inthis i am adding facility
var facility = new Facility
{
Location = "LocA",
// assiging same entity to facility so that it will not treat it as a new contact
Contact = contact
};
contact.Facilities.Add(facility);
// Finaly update the state of the entity .
ctx.Entry(contact).State = EntityState.Modified;
ctx.SaveChanges();
}
}
After this it will not insert new contact when you save in . In my example I choose to add new facility but keep contact same . You can do same with facility but the concept is same . First read the object from EF coontext update values which you need to update and set state to Modified . This will tell that all other Entities in graph are same expect which you modified.
SQL Profiler Query to make sure Update happn for Contact and insert for facility
exec sp_executesql N'UPDATE [dbo].[Contacts]
SET [Name] = #0, [ContactTypeId] = #1
WHERE ([ContactId] = #2)
',N'#0 nvarchar(max) ,#1 int,#2 int',#0=N'Updated',#1=1,#2=1
go
exec sp_executesql N'INSERT [dbo].[Facilities]([Location], [ContactId], [Contact_ContactId])
VALUES (#0, #1, #2)
SELECT [FacilityId]
FROM [dbo].[Facilities]
WHERE ##ROWCOUNT > 0 AND [FacilityId] = scope_identity()',N'#0nvarchar(max) ,#1 int,#2 int',#0=N'LocA',#1=1,#2=1
go
Category model is self referencing
public class Category
{
[Key]
public int CategoryID { get; set; }
public string Name { get; set; }
public int? ParentID { get; set; }
public Category Cat { get; set; }
public ICollection<Category> Categories { get; set; }
public ICollection<BusinessDetail> BDetails { get; set; }
}
and BusinessDetail is like
public class BusinessDetail
{
[Key]
public int ID { get; set; }
[Required]
[Display(Name="Business Name")]
public string BusinessName { get; set; }
public string Address { get; set; }
[Display(Name="Contact")]
public string contactDetail { get; set; }
// public int CategoryID { get; set; }
// public Category Category { get; set; }
public int ? LocationID { get; set; }
public Location Location { get; set; }
[Display(Name="Website Address")]
public string Website_Address { get; set; }
[Display(Name="Is Verified")]
public bool Is_verified { get; set; }
[Required]
[Display(Name="Added By")]
public string Added_By { get; set; }
[Required]
[Display(Name="Added Date")]
[DataType(DataType.DateTime)]
public DateTime Added_Date { get; set; }
[Display(Name="Is Featured")]
public bool Is_Featured { get; set; }
public string Latitude { get; set; }
public string VerifiedBy { get; set; }
public string Longitude { get; set; }
public ICollection<Category> Categories { get; set; }
}
When creating a many-to-many relationship using Fluent API
modelBuilder.Entity<BusinessDetail>()
.HasMany(c => c.Categories).WithMany(i => i.BDetails)
.Map(t => t.MapLeftKey("ID")
.MapRightKey("CategoryID")
.ToTable("BusinessCategories"));
I get this error
There are no primary or candidate keys in the referenced table
'dbo.BusinessDetails' that match the referencing column list in the
foreign key 'FK_dbo.BusinessCategories_dbo.BusinessDetails_ID'.
I need help on this error.
I will try to work out your exact example, but the code below works without any configuration:
EDIT:
I added in the code from OnModelCreating and changed the property names to those in your exampe, but it all keeps working. You do realize though, that the ParentId property is not seen as the foreign key for a parent Category, but that EF will create a Cat_CategoryId foreign key for you?
I advise to start from scratch using my code and work step by step towards the existing code.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.Data.Entity;
public class CategoryContext : DbContext
{
public DbSet<Category> Categories { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Fill in later.
}
}
public class Category
{
public Category()
{
Children = new List<Category>();
Details = new List<BussinesDetail>();
}
public int Id { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Category Parent { get; set; }
public virtual ICollection<Category> Children { get; set; }
public virtual ICollection<BussinesDetail> Details { get; set; }
}
public class BussinesDetail
{
public int Id { get; set; }
public string BussinesName { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
static class Module1
{
public static void Main()
{
using (context = new CategoryContext()) {
var newCat = context.Categories.Add(new Category { Name = "CatOne" });
context.SaveChanges();
newCat = context.Categories.Single;
Console.WriteLine(newCat.Name);
Console.ReadLine();
}
}
}
Here is the model for Organization and Marker:
using System;
using System.Collections.Generic;
using System.Data.Entity.Spatial;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace MyApp.Models
{
public class Orgainzation
{
public int ID { get; set; }
[Required]
[MaxLength(50, ErrorMessage = "Name cannot be longer than 20 characters.")]
public string Name{ get; set; }
[Required]
public int MarkerId { get; set; }
[Required]
public int SystemMarkerId { get; set; }
public virtual Marker Marker{ get; set; }
[ForeignKey("SystemMarkerId")]
public virtual Marker SystemMarker { get; set; }
}
public class Marker
{
public int ID { get; set; }
[Required]
[Display(Name="Marker")]
public string MarkerName{ get; set; }
public virtual ICollection<Organization> Organizations { get; set; }
[InverseProperty("SystemMarkerId")]
public virtual ICollection<Organization> SystemOrganizations { get; set; }
}
}
Here is the DbContext with the override of OnModelCreating:
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace MyApp.Models
{
public class MyAppDb : DbContext
{
public MyAppDb() : base("DefaultContextDb") { }
public DbSet<MyApp.Models.Organization> Organizations { get; set; }
public DbSet<MyApp.Models.Marker> Markers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<MyApp.Models.Organization>()
.HasRequired(x => x.Marker).WithMany(x => x.Organizations).WillCascadeOnDelete(false);
modelBuilder.Entity<MyApp.Models.Organization>()
.HasRequired(x => x.SystemMarker).WithMany(x => x.SystemOrganizations).WillCascadeOnDelete(false);
}
}
}
Here is the migration created with the inappropriate cascadeDelete: true set on the foreign key SystemMarkerId:
public partial class Initial : DbMigration
{
public override void Up()
{
CreateTable(
"dbo.Organization",
c => new
{
ID = c.Int(nullable: false, identity: true),
Name= c.String(maxLength: 50),
MarkerId = c.Int(nullable: false),
SystemMarkerId = c.Int(nullable: false),
})
.PrimaryKey(t => t.ID)
.ForeignKey("dbo.Markers", t => t.MarkerId)
.ForeignKey("dbo.Markers", t => t.SystemMarkerId, cascadeDelete: true)
.Index(t => t.MarkerId)
.Index(t => t.SystemMarkerId);
}
}
Why did it do this and how do I make it stop?
Our ASP.NET C# web application is used in the following environment .NET Framework 4
ASP.NET Web Forms.
IIS 7
Windows 2008
Visual Studio 2010
.NET IDE C#
HTTPS ( SSL )
-Entity Framework 5
In our application, we have the following tables.
1) LearningCart
2) EnrollmentEntriesInLearningCarts
3) EnrollmentEntry
4) Tutorial
5) aspnet_Users
There is a many-to-many relationship between the LearningCart and the EnrollmentEntry tables ( which have the EnrollmentEntriesInLearningCarts bridge table)
The many-to-many relationship between the LearningCart and the EnrollmentEntry tables are depicted in the following Database diagram picture:
Also, I also ensured that the EnrollmentEntriesInLearningCarts bridge table already had data inside it:
namespace PerlsData.Domain
{
using System;
using System.Collections.Generic;
public partial class LearningCart
{
public LearningCart()
{
}
public virtual System.Guid LearningCartsDatabaseId { get; set; }
public virtual short Type { get; set; }
public virtual short Status { get; set; }
public virtual string LearningCartsName { get; set; }
public virtual Nullable<System.Guid> Creator { get; set; }
public virtual Nullable<System.Guid> TeamLead { get; set; }
public virtual Nullable<short> isSubmitted { get; set; }
public virtual Nullable<short> isRemoved { get; set; }
public virtual Nullable<System.DateTime> DateSharedWithInstructor { get; set; }
public virtual ICollection<EnrollmentEntry> associatedEnrollmentEntry { get; set; }
}
}
namespace PerlsData.Domain
{
using System;
using System.Collections.Generic;
public partial class EnrollmentEntry
{
public EnrollmentEntry()
{
}
public virtual System.Guid EnrollmentEntryDatabaseID { get; set; }
public virtual System.Guid UserId { get; set; }
public virtual System.Guid TutorialDatabaseID { get; set; }
public virtual aspnet_Users aspnet_Users { get; set; }
public virtual Tutorial Tutorial { get; set; }
public virtual ICollection<LearningCart> associatedLearningCart { get; set; }
}
}
namespace PerlsData.Domain
{
using System;
using System.Collections.Generic;
public partial class aspnet_Users
{
public aspnet_Users()
{
}
public System.Guid ApplicationId { get; set; }
public System.Guid UserId { get; set; }
public string UserName { get; set; }
public string LoweredUserName { get; set; }
public string MobileAlias { get; set; }
public bool IsAnonymous { get; set; }
public System.DateTime LastActivityDate { get; set; }
}
}
namespace PerlsData.Domain
{
using System;
using System.Collections.Generic;
public partial class Tutorial
{
public Tutorial()
{
}
public virtual System.Guid TutorialDatabaseID { get; set; }
public virtual string TutorialCode { get; set; }
public virtual System.Guid SectionDatabaseID { get; set; }
public virtual System.Guid UserId { get; set; }
public virtual aspnet_Users aspnet_Users { get; set; }
public virtual ICollection<EnrollmentEntry> EnrollmentEntries { get; set; }
public virtual Section Section { get; set; }
}
}
namespace PerlsData
{
public class Context : System.Data.Entity.DbContext
{
public DbSet<PerlsData.Domain.EnrollmentEntry> EnrollmentEntries { get; set; }
public DbSet<PerlsData.Domain.LearningCart> LearningCarts { get; set; }
public Context()
: base("Name=LocalSqlServer")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<PerlsData.Domain.LearningCart>().ToTable("LearningCarts", schemaName: "dbo");
modelBuilder.Entity<PerlsData.Domain.LearningCart>().HasKey(t => t.LearningCartsDatabaseId);
modelBuilder.Entity<PerlsData.Domain.LearningCart>().Property(t => t.LearningCartsDatabaseId)
.HasColumnName("LearningCartsDatabaseId")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<PerlsData.Domain.LearningCart>().HasMany(learnC => learnC.associatedEnrollmentEntry)
.WithMany(enEnt => enEnt.associatedLearningCart)
.Map(
m =>
{
m.ToTable("EnrollmentEntriesInLearningCarts", schemaName: "dbo");
m.MapLeftKey("LearningCartsDatabaseId");
m.MapRightKey("EnrollmentEntryDatabaseID");
}
);
modelBuilder.Entity<PerlsData.Domain.EnrollmentEntry> ().ToTable("EnrollmentEntry", schemaName: "dbo");
modelBuilder.Entity<PerlsData.Domain.EnrollmentEntry>().HasKey(e => e.EnrollmentEntryDatabaseID);
modelBuilder.Entity<PerlsData.Domain.EnrollmentEntry>().Property(t => t.EnrollmentEntryDatabaseID)
.HasColumnName("EnrollmentEntryDatabaseID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<PerlsData.Domain.EnrollmentEntry>().Property(t => t.TutorialDatabaseID)
.HasColumnName("TutorialDatabaseID");
modelBuilder.Entity<PerlsData.Domain.EnrollmentEntry>().HasMany(enEnt => enEnt.associatedLearningCart)
.WithMany(learnC => learnC.associatedEnrollmentEntry)
.Map(
m =>
{
m.ToTable("EnrollmentEntriesInLearningCarts", schemaName: "dbo");
m.MapLeftKey("EnrollmentEntryDatabaseID");
m.MapRightKey("LearningCartsDatabaseId");
}
);
modelBuilder.Entity<PerlsData.Domain.aspnet_Users>().ToTable("aspnet_Users", schemaName: "dbo");
modelBuilder.Entity<PerlsData.Domain.aspnet_Users>()
.Property(au => au.UserId)
.HasColumnName("UserId");
modelBuilder.Entity<PerlsData.Domain.aspnet_Users>()
.HasKey(au => au.UserId);
modelBuilder.Entity<PerlsData.Domain.aspnet_Users>()
.Property(au => au.UserName)
.HasColumnName("UserName");
modelBuilder.Entity<PerlsData.Domain.Tutorial>().ToTable("Tutorial", schemaName: "dbo");
modelBuilder.Entity<PerlsData.Domain.Tutorial>().Property(t => t.TutorialDatabaseID)
.HasColumnName("TutorialDatabaseID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
modelBuilder.Entity<PerlsData.Domain.Tutorial>()..HasKey(t => t.TutorialDatabaseID);
modelBuilder.Entity<PerlsData.Domain.Tutorial>().HasRequired(x => x.Section)
.WithMany(x => x.Tutorials)
.HasForeignKey(x => x.SectionDatabaseID);
}
}
}
Here's is where the code fails to retrieve information:
public LearningCart getLearningCartAssociatedWithLoggedInStudentsTutorial(Guid userOfInterestGuid, Guid tutorialOfInterestGuid){
LearningCart learningCartsAssociatedWithLoggedInStudentTutorial = new LearningCart();
EnrollmentEntry enrollmentEntryAssociatedWithLoggedInStudentTutorial = new EnrollmentEntry();
LearningCart learnCartOfInterest = null;
IQueryable<LearningCart> learnCartIQueryable = null;
EnrollmentEntry enrEntOfInterest = null;
using (PerlsData.Context context = new PerlsData.Context())
{
context.Configuration.LazyLoadingEnabled = true;
context.Configuration.ProxyCreationEnabled = true;
IQueryable<EnrollmentEntry> enrollmentEntryOfInterestIQueryable =
context.EnrollmentEntries.Where(ee =>
ee.aspnet_Users.UserId == userOfInterestGuid
&& ee.Tutorial.TutorialDatabaseID == tutorialOfInterestGuid);
foreach (EnrollmentEntry enrEnt in enrollmentEntryOfInterestIQueryable)
{
enrEntOfInterest = enrEnt;
}
learnCartIQueryable = context.LearningCarts.Where(lc =>
lc.associatedEnr ollmentEntry.Any(ee =>
ee.EnrollmentEntryDatabaseID == enrEntOfInterest.EnrollmentEntryDatabaseID));
foreach (LearningCart lc in learnCartIQueryable)
{
learnCartOfInterest = lc;
}
context.Entry(learnCartOfInterest).State = System.Data.EntityState.Detached;
}
return learnCartOfInterest;
}
The problem comes about with trying to figure out a specific LearningCart module.
I try to retrieve a LearningCart, and place it in the IQueryable object:
IQueryable<LearningCart> learnCartIQueryable = context.LearningCarts.Where(lc =>
lc.associatedEnrollmentEntry.Any(ee =>
ee.EnrollmentEntryDatabaseID == enrEntOfInterest.EnrollmentEntryDatabaseID));
Using Visual Studio 2010, I put learnCartIQueryable under "Add Watch", and I got "Enumeration yielded no results"
I already do have data inside in the EnrollmentEntriesInLearningCarts bridge table.
Why is it that Entity Framework fails to retrieve the data in the EnrollmentEntriesInLearningCarts bridge table, and only gives the error "Enumeration yielded no results" ?
the sample code on http://msdn.microsoft.com/en-US/data/jj591620#RequiredToRequired is it even correct? the code is asking for OfficeAssignment prop on the Instructor class. it will not resolve for obvious reasons. what is the correct way of having a one-to-one relationship on ef now?
// Configure the primary key for the OfficeAssignment
modelBuilder.Entity<OfficeAssignment>()
.HasKey(t => t.InstructorID);
modelBuilder.Entity<Instructor>()
.HasRequired(t => t.OfficeAssignment)
.WithRequiredPrincipal(t => t.Instructor);
public class OfficeAssignment
{
// Specifying InstructorID as a primary
[Key()]
public Int32 InstructorID { get; set; }
public string Location { get; set; }
// When the Entity Framework sees Timestamp attribute
// it configures ConcurrencyCheck and DatabaseGeneratedPattern=Computed.
[Timestamp]
public Byte[] Timestamp { get; set; }
// Navigation property
public virtual Instructor Instructor { get; set; }
}
public class Instructor
{
public Instructor()
{
this.Courses = new List<Course>();
}
// Primary key
public int InstructorID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
public System.DateTime HireDate { get; set; }
// Navigation properties
public virtual ICollection<Course> Courses { get; private set; }
}
There is mistake around the Local/office nav property. A few deliberate renames to clarify
Perhaps this....
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace one2one
{
class Program
{
static void Main(string[] args)
{
var context = new Demo();
var instructor = new Instructor();
instructor.FirstName = "Big";
instructor.LastName = "Willi";
context.Set<Instructor>().Add(instructor);
var office = new OfficeAssignment();
office.Location = "is this where the demo broke down ? See POCO ";
office.InstructorUsingThisOffice = instructor;
context.Set<OfficeAssignment>().Add(office);
context.SaveChanges();
}
}
public class OfficeAssignment
{
// Specifying InstructorID as a primary
public Int32 InstructorID { get; set; }
public string Location { get; set; }
// Navigation property
public virtual Instructor InstructorUsingThisOffice { get; set; }
}
public class Instructor
{
// Primary key
public int InstructorID { get; set; }
public string LastName { get; set; }
public string FirstName { get; set; }
//navigation
//missing
public virtual OfficeAssignment TheofficeToUse { get; set; }
}
public class Demo : DbContext
{
DbSet<OfficeAssignment> officeAssignments { get; set; }
DbSet<Instructor> Instructors { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure the primary key for the OfficeAssignment
modelBuilder.Entity<OfficeAssignment>()
.HasKey(t => t.InstructorID);
modelBuilder.Entity<Instructor>()
.HasRequired(t => t.TheofficeToUse)
.WithRequiredPrincipal(d => d.InstructorUsingThisOffice); //current entity is principal, the navigation back.
// and we share the same key... MUST with EF 1:1 foreign key
}
}
}