Why EF doesnt update navigation property - entity-framework

I use Code First EF 5.0 on >Net 4.0 and I has 2 class:
public partial class Kennel
{
public Kennel()
{
this.Brands = new List<Brand>();
this.Dogs = new List<Dog>();
this.Breeds = new List<Breed>();
this.Owners = new List<Person>();
this.Name1 = new KennelName();
this.Name2 = new KennelName();
}
public int ID { get; set; }
public /*DogClub*/int Type { get; set; }
public KennelName Name1 { get; set; }
public KennelName Name2 { get; set; }
public string CertificateNumber { get; set; }
public System.DateTime? AssigmentDate { get; set; }
public string Folder { get; set; }
public string Comment { get; set; }
public int StatusID { get; set; }
public int? FederationID { get; set; }
public int? MainOwnerID { get; set; }
public int? MainBreedID { get; set; }
public virtual ICollection<Brand> Brands { get; set; }
public virtual ICollection<Dog> Dogs { get; set; }
public virtual Breed MainBreed { get; set; }
public virtual Federation Federation { get; set; }
public virtual Status Status { get; set; }
public virtual Person MainOwner { get; set; }
public virtual ICollection<Breed> Breeds { get; set; }
public virtual ICollection<Person> Owners { get; set; }
}
public partial class Breed
{
public Breed()
{
this.Dogs = new List<Dog>();
this.ExpertKerungs = new List<ExpertKerung>();
this.Hallmarks = new List<Hallmark>();
this.Colors = new List<Color>();
this.ExpertBreeds = new List<ExpertBreed>();
this.Kennels = new List<Kennel>();
this.MainKennels = new List<Kennel>();
}
public int ID { get; set; }
public string FciNumber { get; set; }
public string Name { get; set; }
public int BreedGroupID { get; set; }
public bool IsKerung { get; set; }
public string NameLat { get; set; }
public string NativeName { get; set; }
public int CountryID { get; set; }
public System.DateTime? StandardDate { get; set; }
public bool IsCACIB { get; set; }
public bool IsWork { get; set; }
public virtual BreedGroup BreedGroup { get; set; }
public virtual ICollection<Dog> Dogs { get; set; }
public virtual ICollection<ExpertKerung> ExpertKerungs { get; set; }
public virtual ICollection<Hallmark> Hallmarks { get; set; }
public virtual ICollection<Color> Colors { get; set; }
public virtual Country Country { get; set; }
public virtual ICollection<ExpertBreed> ExpertBreeds { get; set; }
public virtual ICollection<Kennel> Kennels { get; set; }
public virtual ICollection<Kennel> MainKennels { get; set; }
}
and mapping:
public class KennelMap : EntityTypeConfiguration<Kennel>
{
public KennelMap()
{
// Primary Key
this.HasKey(t => t.ID);
// Properties
//this.Property(t => t.Name1.Name)
// .IsRequired();
//this.Property(t => t.Name1.IntlName)
// .IsRequired();
//this.Property(t => t.Name2.Name)
// .IsRequired();
//this.Property(t => t.Name2.IntlName)
// .IsRequired();
// Table & Column Mappings
this.ToTable("Kennels");
this.Property(t => t.ID).HasColumnName("ID");
this.Property(t => t.Type).HasColumnName("Type");
this.Property(t => t.Name1.Name).HasColumnName("Name1_Name");
this.Property(t => t.Name1.IntlName).HasColumnName("Name1_IntlName");
this.Property(t => t.Name1.Type).HasColumnName("Name1_Type");
this.Property(t => t.Name1.Approved).HasColumnName("Name1_Approved");
this.Property(t => t.Name2.Name).HasColumnName("Name2_Name");
this.Property(t => t.Name2.IntlName).HasColumnName("Name2_IntlName");
this.Property(t => t.Name2.Type).HasColumnName("Name2_Type");
this.Property(t => t.Name2.Approved).HasColumnName("Name2_Approved");
this.Property(t => t.CertificateNumber).HasColumnName("CertificateNumber");
this.Property(t => t.AssigmentDate).HasColumnName("AssigmentDate");
this.Property(t => t.Folder).HasColumnName("Folder");
this.Property(t => t.Comment).HasColumnName("Comment");
this.Property(t => t.StatusID).HasColumnName("StatusID");
this.Property(t => t.FederationID).HasColumnName("FederationID");
this.Property(t => t.MainOwnerID).HasColumnName("MainOwnerID");
// Relationships
this.HasMany(t => t.Owners)
.WithMany(t => t.Kennels)
.Map(m =>
{
m.ToTable("OwnerKennel");
m.MapLeftKey("Kennels_ID");
m.MapRightKey("Owners_ID");
});
this.HasOptional(t => t.MainBreed)
.WithMany(t => t.MainKennels)
.HasForeignKey(d => d.MainBreedID);
this.HasOptional(t => t.Federation)
.WithMany(t => t.Kennels)
.HasForeignKey(d => d.FederationID);
this.HasRequired(t => t.Status)
.WithMany(t => t.Kennels)
.HasForeignKey(d => d.StatusID);
this.HasOptional(t => t.MainOwner)
.WithMany(t => t.MainKennels)
.HasForeignKey(d => d.MainOwnerID)
.WillCascadeOnDelete(false);
}
}
If I write next code:
int breedID = 1; // some value
Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);
if (br != null)
{
_kennel.MainBreed = br;
// but: _kennel.MainBreedID != br.ID
}
OR:
int breedID = 1; // some value
Breed br = _kennel.Breeds.FirstOrDefault(t => t.ID == breedID);
if (br != null)
{
_kennel.MainBreedID = breedID;
// but: _kennel.MainBreed != br
}
Why EF doesnt update navigation property? I set ProxyCreationEnabled and AutoDetectChangesEnabled, but this not work.
See another example of sample code (it accurately reflects my real application code):
Kennel kennel = ctx.Kennels.Add(ctx.Kennels.Create());
kennel.Name1.Name = "Test Kennel";
List<Breed> breeds = ctx.Breeds.Include(b => b.BreedGroup).OrderBy(t => t.BreedGroupID).Where(t => t.ID == 755 || t.ID == 772).ToList();
foreach (var b in breeds)
kennel.Breeds.Add(b);
if (breeds.Count > 0)
{
kennel.MainBreed = breeds[0];
foreach (var k in kennel.MainBreed.MainKennels)
System.Diagnostics.Debug.WriteLine("MainKennel: " + k.Name1.Name);
ctx.ChangeTracker.DetectChanges();
//System.Diagnostics.Debug.WriteLine("MainBreed: " + kennel.MainBreed);
System.Diagnostics.Debug.WriteLine("MainBreedID: " + kennel.MainBreedID);
}
After call to DetectChanges all navigation properties and collection reflect changes (kennel.MainBreedID != null).

Try making all your POCO properties virtual rather than just the navigation properties. This will allow EF to create change tracking proxies rather than lazy loading proxies. I've not tested this, but you may then get the behavior that you expect.

Remove the intialisation of the collections from the constructor
//this.Dogs = new List<Dog>();
//this.ExpertKerungs = new List<ExpertKerung>();
//this.Hallmarks = new List<Hallmark>();
//this.Colors = new List<Color>();
//this.ExpertBreeds = new List<ExpertBreed>();
//this.Kennels = new List<Kennel>();
//this.MainKennels = new List<Kennel>();

Related

Entity Framework mysterious error

Please help. I don`t understand why from my entity context
var stagesExist = context.WfwDocumentWorkStages
.Any(it => it.Enabled && it.ExecutionId == execution.Id
&& it.Level == execution.Level && it.ResultId == null);
value stagesExist is false
But
var stages = context.WfwDocumentWorkStages.Where(it => it.Enabled
&& it.ExecutionId == execution.Id
&& it.Level == execution.Level).ToList();
bool stagesExist = stages.Any(it=>it.ResultId == null);
value stagesExist is true??
Model:
public partial class WfwDocumentWorkScheme : EnabledEntity
{
public WfwDocumentWorkScheme()
{
this.WfwExecutionEvents = new List<WfwExecutionEvent>();
}
public int ExecutionId { get; set; }
public int Level { get; set; }
public int? RoleId { get; set; }
public string CoordinatorSid { get; set; }
public DateTimeOffset? Date { get; set; }
public int? ResultId { get; set; }
public string Comment { get; set; }
public virtual Employee Coordinator { get; set; }
public virtual EmployeeRole EmployeeRole { get; set; }
public virtual WfwEventResult WfwEventResult { get; set; }
public virtual WfwDocumentExecution WfwDocumentExecution { get; set; }
public virtual ICollection<WfwExecutionEvent> WfwExecutionEvents { get; set; }
}
Mapping
public class WfwDocumentWorkSchemeMap : EntityTypeConfiguration<WfwDocumentWorkScheme>
{
public WfwDocumentWorkSchemeMap()
{
// Primary Key
this.HasKey(t => t.Id);
// Properties
this.Property(t => t.CoordinatorSid)
.HasMaxLength(46);
// Table & Column Mappings
this.ToTable("WfwDocumentWorkSchemes");
this.Property(t => t.Id).HasColumnName("Id");
this.Property(t => t.ExecutionId).HasColumnName("ExecutionId");
this.Property(t => t.Level).HasColumnName("Level");
this.Property(t => t.RoleId).HasColumnName("RoleId");
this.Property(t => t.CoordinatorSid).HasColumnName("CoordinatorSid");
this.Property(t => t.Date).HasColumnName("Date");
this.Property(t => t.ResultId).HasColumnName("ResultId");
this.Property(t => t.Comment).HasColumnName("Comment");
this.Property(t => t.Enabled).HasColumnName("Enabled");
// Relationships
this.HasRequired(t => t.Coordinator)
.WithMany(t => t.WfwDocumentWorkSchemes)
.HasForeignKey(d => d.CoordinatorSid);
this.HasRequired(t => t.WfwDocumentExecution)
.WithMany(t => t.WfwDocumentWorkSchemes)
.HasForeignKey(d => d.ExecutionId);
this.HasRequired(t => t.WfwEventResult)
.WithMany(t => t.WfwDocumentWorkSchemes)
.HasForeignKey(d => d.ResultId);
this.HasOptional(t => t.EmployeeRole)
.WithMany(t => t.WfwDocumentWorkSchemes)
.HasForeignKey(d => d.RoleId);
}
}
Result model contains virtual List
public class WfwEventResult : EnabledEntity
{
public WfwEventResult()
{
this.WfwExecutionEvents = new List<WfwExecutionEvent>();
this.WfwDocumentWorkSchemes = new List<WfwDocumentWorkScheme>();
}
public string Name { get; set; }
public string Description { get; set; }
public bool Success { get; set; }
public virtual ICollection<WfwExecutionEvent> WfwExecutionEvents { get; set; }
public virtual ICollection<WfwDocumentWorkScheme> WfwDocumentWorkSchemes { get; set; }
}
The problem is this line in your mapping:
this.HasRequired(t => t.WfwEventResult)
You are effectively telling the EF that the associated FK column will never be null (although you've made it int? and have records with null value). Remember that EF uses metadata information when building SQL queries, and in this case I guess the query optimizer decides that this query will never return records (similar to .Where(it => false)) and generates a fake SQL query you see.
Shortly - make sure you always provide the correct information to EF. In this case, change the above to
this.HasOptional(t => t.WfwEventResult)
and you'll see a different (real) query and get a correct results.

EntityType 'FollowerMenuItemMerchant' has no key defined. Define the key for this EntityType

Other people have asked this question and I checked to see if I was making the same errors, and it appears I am not, from what I can tell.
Here is my FollowerMenuItemMerchant class.
public class FollowerMenuItemMerchant
{
[key, Column(Order = 0)]
public int FollowerID { get; set; }
[key, Column(Order = 1)]
public int MenuItemID { get; set; }
[key, Column(Order = 2)]
public int MerchantID { get; set; }
public virtual Follower Follower { get; set; }
public virtual MenuItem MenuItem { get; set; }
public virtual Merchant Merchant { get; set; }
}
And here is the Context class:
public class FlavorPingContext : IdentityDbContext<ApplicationUser>
{
public FlavorPingContext() : base("name=FlavorPingContext")
{
}
public System.Data.Entity.DbSet<FlavorPing.Models.Merchant> Merchants { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MenuItem> MenuItems { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.MerchantDetails> MerchantDetails { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.Follower> Followers { get; set; }
public System.Data.Entity.DbSet<FlavorPing.Models.FollowerMenuItemMerchant> FollowerMenuItemMerchants { get; set; }
protected override void OnModelCreating(DbModelBuilder builder) {
// Primary keys
builder.Entity<Follower>().HasKey(q => q.FollowerID);
builder.Entity<MenuItem>().HasKey(q => q.MenuItemID);
builder.Entity<Merchant>().HasKey(q => q.MerchantID);
builder.Entity<FollowerMenuItemMerchant>().HasKey(q =>
new {
q.FollowerID, q.MenuItemID, q.MerchantID
});
// Relationships
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Follower)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.FollowerID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.MenuItem)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MenuItemID);
builder.Entity<FollowerMenuItemMerchant>()
.HasRequired(t => t.Merchant)
.WithMany(t => t.FollowerMenuItemMerchants)
.HasForeignKey(t => t.MerchantID);
}
}
Can you see where there may be an error?
Yikes, I found it! I used lower case "key", and not uppercase "Key"! Doh!

Entity Framework 6: Add to child collections

I am using EF6 code first. I have an parent entity (Expense) which has collection of child entity (Tag). Entities are
public class Expense : Entity
{
//public Expense()
//{
// this.Tags = new HashSet<Tag>();
//}
public string Title { get; set; }
public ICollection<Tag> Tags { get; set; }
//public long TagId { get; set; }
public decimal Amount { get; set; }
public long ByUserId { get; set; }
public User ByUser { get; set; }
public long? ForUserId { get; set; }
public User ForUser { get; set; }
public DateTime ExpenseDate { get; set; }
}
public class Tag : Entity
{
public Tag()
{
this.Expenses = new HashSet<Expense>();
}
public string Name { get; set; }
public virtual ICollection<Expense> Expenses { get; set; }
public long OrganizationId { get; set; }
public Organization Organization { get; set; }
}
Configured as
public ExpenseConfiguration()
{
this.HasRequired(x => x.ByUser)
.WithMany()
.HasForeignKey(x => x.ByUserId)
.WillCascadeOnDelete(false);
this.HasOptional(x => x.ForUser)
.WithMany()
.HasForeignKey(x => x.ForUserId)
.WillCascadeOnDelete(false);
this.HasMany(x => x.Tags)
.WithMany(t => t.Expenses)
.Map(et => {
et.MapLeftKey("ExpenseId");
et.MapRightKey("TagId");
et.ToTable("tblExpenseTags");
});
}
public TagConfiguration()
{
this.HasRequired(x => x.Organization)
.WithMany()
.HasForeignKey(p => p.OrganizationId)
.WillCascadeOnDelete(false);
}
The way I am saving entity
var tags = new List<Tag>();
foreach (var item in expense.Tags)
{
var tag = _TagHandler.Get().Where(x => x.Id == item.Id).FirstOrDefault();
tags.Add(tag);
}
entity.Tags.Clear();
foreach (var item in tags)
{
expense.Tags.Add(item);
}
if (expense.Id == 0)
{
entity.CreatedDate = DateTime.UtcNow;
entity.UpdatedDate = DateTime.UtcNow;
updated = EntityRepository.Add(entity);
}
else
{
expense.UpdatedDate = DateTime.UtcNow;
updated = EntityRepository.Update(entity);
}
UnitOfWork.Commit();
When i Create Expense I add multiple tags to it and it save successfully in tblExpenseTags, but the problem is when I add new tags to Expense they are not saving into tblExpenseTags table. I used sql profiler to see what calls are going to SQL database and I don't see any insert call at the time of update expense.
Please let me know what wrong am I doing ?

Why am I getting Invalid column name on field names that don't exist in my model?

I am querying an entity with EF 5.0 Code First / DbContext. I am getting the following errors:
Invalid column name 'RetainedEarningsAccount_Key'.
Invalid column name 'PLSummaryAccount_Key'.
However, neither of these fields exist in the model. I assume some default configuration/mapping is happening here, but I don't know what it is. Here is the model class in question:
public GLEntity()
{
this.AccessEntities = new HashSet<AccessEntity>();
this.BankAccountGLAccounts = new HashSet<BankAccountGLAccount>();
this.BatchRestrictionEntities = new HashSet<BatchRestrictionEntity>();
this.BudgetVersions = new HashSet<BudgetVersion>();
this.CalendarCrossRefs = new HashSet<CalendarCrossRef>();
this.ConsolDetails = new HashSet<ConsolDetail>();
this.ConsolHeaders = new HashSet<ConsolHeader>();
this.DefaultBudgetVersions = new HashSet<DefaultBudgetVersion>();
this.Departments = new HashSet<Department>();
this.ExpenseCodeDetails = new HashSet<ExpenseCodeDetail>();
this.GLAccounts = new HashSet<GLAccount>();
this.Journals = new HashSet<Journal>();
this.PostingRules = new HashSet<PostingRule>();
this.Processes = new HashSet<Process>();
this.Properties = new HashSet<Property>();
this.RecurringJournals = new HashSet<RecurringJournal>();
this.RecurringTransactionGLs = new HashSet<RecurringTransactionGL>();
this.EntitiesAlternate = new HashSet<GLEntity>();
this.GLIntercompaniesDestinationEntities = new HashSet<GLIntercompany>();
this.GLIntercompaniesSourceEntities = new HashSet<GLIntercompany>();
this.TransGLs = new HashSet<TransGL>();
}
public System.Guid Key { get; set; }
public string EntityID { get; set; }
public string Description { get; set; }
public Nullable<short> CurrentFiscalYear { get; set; }
public Nullable<short> CurrentPrd { get; set; }
public string EntityType { get; set; }
public string AllowPostingYN { get; set; }
public string NextJournal { get; set; }
public Nullable<System.Guid> CompanyKey { get; set; }
public Nullable<System.Guid> RetainedEarningsAcctKey { get; set; }
public Nullable<System.Guid> PLSummaryAcctKey { get; set; }
public string AccountingType { get; set; }
public string UserCreated { get; set; }
public System.DateTime Created { get; set; }
public string UserEdited { get; set; }
public Nullable<System.DateTime> Edited { get; set; }
public Nullable<System.Guid> AlternateEntityKey { get; set; }
public string TrackJobs { get; set; }
public string TrackUnits { get; set; }
public virtual ICollection<AccessEntity> AccessEntities { get; set; }
public virtual ICollection<BankAccountGLAccount> BankAccountGLAccounts { get; set; }
public virtual ICollection<BatchRestrictionEntity> BatchRestrictionEntities { get; set; }
public virtual ICollection<BudgetVersion> BudgetVersions { get; set; }
public virtual ICollection<CalendarCrossRef> CalendarCrossRefs { get; set; }
public virtual Company Company { get; set; }
public virtual ICollection<ConsolDetail> ConsolDetails { get; set; }
public virtual ICollection<ConsolHeader> ConsolHeaders { get; set; }
public virtual ICollection<DefaultBudgetVersion> DefaultBudgetVersions { get; set; }
public virtual ICollection<Department> Departments { get; set; }
public virtual ICollection<ExpenseCodeDetail> ExpenseCodeDetails { get; set; }
public virtual ICollection<GLAccount> GLAccounts { get; set; }
public virtual ICollection<Journal> Journals { get; set; }
public virtual ICollection<PostingRule> PostingRules { get; set; }
public virtual ICollection<Process> Processes { get; set; }
public virtual ICollection<Property> Properties { get; set; }
public virtual ICollection<RecurringJournal> RecurringJournals { get; set; }
public virtual ICollection<RecurringTransactionGL> RecurringTransactionGLs { get; set; }
public virtual ICollection<GLEntity> EntitiesAlternate { get; set; }
public virtual GLEntity EntityAlternate { get; set; }
public virtual ICollection<GLIntercompany> GLIntercompaniesDestinationEntities { get; set; }
public virtual ICollection<GLIntercompany> GLIntercompaniesSourceEntities { get; set; }
public virtual ICollection<TransGL> TransGLs { get; set; }
public virtual GLAccount RetainedEarningsAccount { get; set; }
public virtual GLAccount PLSummaryAccount { get; set; }
}
And here is the mapping:
public GLEntity_Mapping()
{
this.HasKey(t => t.Key);
this.ToTable("tblEntity");
this.Property(t => t.Key).HasColumnName("KeyGUID");
this.Property(t => t.EntityID).HasColumnName("EntityID").IsUnicode(false).HasMaxLength(10);
this.Property(t => t.Description).HasColumnName("Description").IsUnicode(false).HasMaxLength(50);
this.Property(t => t.CurrentFiscalYear).HasColumnName("CurrentFiscalYear");
this.Property(t => t.CurrentPrd).HasColumnName("CurrentPrd");
this.Property(t => t.EntityType).HasColumnName("EntityType").IsUnicode(false).IsFixedLength().HasMaxLength(1);
this.Property(t => t.AllowPostingYN).HasColumnName("AllowPostingYN").IsUnicode(false).IsFixedLength().HasMaxLength(1);
this.Property(t => t.NextJournal).HasColumnName("NextJournal").IsUnicode(false).HasMaxLength(20);
this.Property(t => t.CompanyKey).HasColumnName("Company");
this.Property(t => t.RetainedEarningsAcctKey).HasColumnName("RetainedEarningsAcct");
this.Property(t => t.PLSummaryAcctKey).HasColumnName("PLSummaryAcct");
this.Property(t => t.AccountingType).HasColumnName("AccountingType").IsUnicode(false).IsFixedLength().HasMaxLength(1);
this.Property(t => t.UserCreated).HasColumnName("UserCreated").IsRequired().IsUnicode(false).HasMaxLength(50);
this.Property(t => t.Created).HasColumnName("Created");
this.Property(t => t.UserEdited).HasColumnName("UserEdited").IsUnicode(false).HasMaxLength(50);
this.Property(t => t.Edited).HasColumnName("Edited");
this.Property(t => t.AlternateEntityKey).HasColumnName("AlternateEntity");
this.Property(t => t.TrackJobs).HasColumnName("TrackJobs").IsUnicode(false).IsFixedLength().HasMaxLength(1);
this.Property(t => t.TrackUnits).HasColumnName("TrackUnits").IsUnicode(false).IsFixedLength().HasMaxLength(1);
this.HasOptional(t => t.Company).WithMany(t => t.Entities).HasForeignKey(d => d.CompanyKey);
this.HasOptional(t => t.EntityAlternate).WithMany(t => t.EntitiesAlternate).HasForeignKey(d => d.AlternateEntityKey);
}
Why am I getting an error on non-existent properties?
Because of the abbreviation Acct instead of Account in these properties...
public Nullable<System.Guid> RetainedEarningsAcctKey { get; set; }
public Nullable<System.Guid> PLSummaryAcctKey { get; set; }
...EF conventions do not recognize the properties as foreign keys for
public virtual GLAccount RetainedEarningsAccount { get; set; }
public virtual GLAccount PLSummaryAccount { get; set; }
You can either rename the FK properties to RetainedEarningsAccountKey and PLSummaryAccountKey. EF should recognize them correctly then according to the rule "FK property name = Navigation property name + primary key name of target entity".
Or define the properties as FKs with Fluent API in your GLEntity_Mapping:
this.HasOptional(t => t.RetainedEarningsAccount)
.WithMany(a => a.SomeInverseCollection1)
.HasForeignKey(t => t.RetainedEarningsAcctKey);
this.HasOptional(t => t.PLSummaryAccount)
.WithMany(a => a.SomeInverseCollection2)
.HasForeignKey(t => t.PLSummaryAcctKey);
SomeInverseCollection1/2 are the related collections in GLAccount or use WithMany() without lambda parameter if there are no inverse collections in that class.

EF Code First Approach: Confused in EF Foreign Key constraint by fluent syntax

I am trying to create a foreign key relation ship with fluent syntax using EF code first approach.
My entities are as follows,
public partial class Defect
{
public int DefectID { get; set; }
public decimal ReleaseNo { get; set; }
public int BuildNo { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public string StepsToReproduce { get; set; }
public int ApplicationModuleID { get; set; }
public int SeverityLevel { get; set; }
public string LoggedBy { get; set; }
public Nullable<System.DateTime> LoggedOn { get; set; }
public string LastModifiedBy { get; set; }
public Nullable<System.DateTime> LastModifiedOn { get; set; }
public string AssignedTo { get; set; }
public string Status { get; set; }
public string ResolutionNote { get; set; }
public Nullable<System.DateTime> ResolvedOn { get; set; }
public int ProjectID { get; set; }
public virtual SeverityIndex SeverityIndex { get; set; }
public virtual User LoggedByUser { get; set; }
public virtual User LastModifiedUser { get; set; }
public virtual User AssignedToUser { get; set; }
public virtual Project Project { get; set; }
}
public class DefectMap:EntityTypeConfiguration<Defect>
{
public DefectMap()
{
this.HasKey(d => d.DefectID);
this.ToTable("Defect");
this.Property(d => d.DefectID)
.IsRequired()
.HasColumnName("DefectID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
this.Property(d => d.Description)
.IsRequired()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(2000)
.HasColumnName("Description")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(d => d.StepsToReproduce)
.IsOptional()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(4000)
.HasColumnName("StepsToReproduce")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(d => d.LastModifiedBy)
.IsOptional()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(10)
.HasColumnName("LastModifiedBy")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(d => d.AssignedTo)
.IsOptional()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(10)
.HasColumnName("AssignedTo")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(d => d.Status)
.IsOptional()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(50)
.HasColumnName("Status")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.Property(d => d.ResolutionNote)
.IsOptional()
.IsUnicode()
.IsVariableLength()
.HasMaxLength(4000)
.HasColumnName("ResolutionNote")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.HasRequired(p => p.Project).WithMany(p => p.DefectList).HasForeignKey(p => p.ProjectID);
this.HasRequired(s => s.SeverityIndex).WithMany(s => s.DefectList).HasForeignKey(s => s.SeverityLevel).WillCascadeOnDelete();
this.HasOptional(u => u.AssignedToUser).WithMany(u => u.AssignedToUserList).HasForeignKey(u => u.AssignedTo).WillCascadeOnDelete();
this.HasOptional(u => u.LastModifiedUser).WithMany(u => u.ModifiedByUserList).HasForeignKey(u => u.LastModifiedBy);
this.HasRequired(u => u.LoggedByUser).WithMany(u => u.LoggedByUserList).HasForeignKey(u => u.LoggedBy);
}
public partial class Project
{
public Project()
{
ApplicationModuleList = new List<ApplicationModule>();
DefectList = new List<Defect>();
UserList = new List<User>();
}
public int ID { get; set; }
public string ProjectName { get; set; }
public string ProjectManager { get; set; }
public Nullable<System.DateTime> ProjectStartDate { get; set; }
public Nullable<System.DateTime> ProjectEstimatedEndDate { get; set; }
public Nullable<System.DateTime> ProjectActualEndDate { get; set; }
public Nullable<int> ProjectBillingModel { get; set; }
public Nullable<decimal> ProjectEstimatedBudget { get; set; }
public Nullable<decimal> ProjectActualBudget { get; set; }
public Nullable<int> ProjectPortfolio { get; set; }
public Nullable<decimal> ProjectBillingRate { get; set; }
public Nullable<int> ProjectEstimatedManHours { get; set; }
public Nullable<int> ProjectActualManHours { get; set; }
public Nullable<int> ProjectIsApproved { get; set; }
public virtual ICollection<ApplicationModule> ApplicationModuleList { get; set; }
public virtual ICollection<Defect> DefectList { get; set; }
public virtual ICollection<User> UserList { get; set; }
public virtual BillingModel BillingModel { get; set; }
public virtual Portfolio Portfolio { get; set; }
public virtual ApprovalStatus ApprovalStatus { get; set; }
}
public class ProjectMap:EntityTypeConfiguration<Project>
{
public ProjectMap()
{
this.HasKey(p => p.ID);
this.ToTable("Projects");
this.Property(p => p.ID)
.HasColumnName("ID")
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired();
this.Property(p => p.ProjectName)
.HasColumnName("ProjectName")
.HasMaxLength(200)
.IsRequired()
.IsVariableLength()
.IsUnicode()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
this.HasOptional(p => p.BillingModel).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectBillingModel).WillCascadeOnDelete();
this.HasOptional(p => p.Portfolio).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectPortfolio).WillCascadeOnDelete();
this.HasOptional(p => p.ApprovalStatus).WithMany(p=>p.Projects).HasForeignKey(p => p.ProjectIsApproved).WillCascadeOnDelete();
}
}
I am trying code first approach for database creation using fluent API.
However when I run the code I get error saying
*Introducing FOREIGN KEY constraint 'FK_dbo.User_dbo.Projects_ProjectID' on table 'User' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. Could not create constraint. See previous errors*
The same error appears for AssignedTo column.
Here I am trying to implement logic where, A project can have many defects and a defect should have an associated Project ID (i.e one to many relationship between project and defect).
Can anyone suggest what is wrong with the code and where should I rectify the code to get things working?
Thanks in advance!!!
EF has Cascade delete on by default, and this will cause problems with your design - as per the error message.
Either add the following
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
or include
WillCascadeOnDelete(false)
in your fluent API