"Introducing FOREIGN KEY constraint 'FK_dbo.AttendanceSheets_dbo.AdulLiteracyTeachers_ALTName' on table 'AttendanceSheets' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.\r\nCould not create constraint. See previous errors."}
public class AttendanceSheet
{
[Required]
[Key]
public int Attendanceid { get; set; }
[DisplayName("District")]
[ForeignKey("District")]
public int DistID { get; set; }
public virtual District District { get; set; }
[DisplayName("District")]
[ForeignKey("AdulLiteracyTeachers")]
public int ALTName { get; set; }
public virtual AdulLiteracyTeachers AdulLiteracyTeachers { get; set; }
[DisplayName("Month")]
public int Month { get; set; }
[DisplayName("Number Of Days")]
public int Attandence { get; set; }
}
Getting the above error while I am adding the controller using entity framework. Purpose is I want to pouplate whole Teacher list for attandance. I am using the foriegn key for teachers name
In your data context file add
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
below where you have your DbSets defined.
This happens when there are multiple paths to delete on entity from another through foreign keys.
For example
EntityA - EntityB - EntityC - EntityD
EntityA - EntityC - EntityD
EntityA - EntityD
There are multiple paths to delete the related EntityD, sql server doesn't allow this.
Related
I am getting error while trying to run my MVC application
Introducing FOREIGN KEY constraint 'FK_dbo.Passages_dbo.Localizations_ToID' on table 'Passages' 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 or index. See previous errors'
I`ve seen many posts but I couldn't get what should I do now.
There are my models:
public class Passage
{
[Key]
public int ID { get; set; }
public int FromID { get; set; }
[ForeignKey("FromID")]
public Localization FromLocalizaton { get; set; }
public int ToID { get; set; }
[ForeignKey("ToID")]
public Localization ToLocalization { get; set; }
public DateTime DepartureTime { get; set; }
public DateTime ArrivalTime { get; set; }
public DateTime? AdditionalTime { get; set; }
public bool Weekend { get; set; }
public int Seats { get; set; }
}
public class Localization
{
[Key]
public int ID { get; set; }
public string Province { get; set; }
public string City { get; set; }
public string PostalCode { get; set; }
public string StreetAdres { get; set; }
}
Passage has two foreign key refers to Lozalization with one to one relationship
The issue came from this:
Passage has two foreign key refers to Lozalization with one to one relationship
Because by default those two relationships are required in Passage (look at foreign key FromID and ToID there are not Nullable<int> or int?) hence Code First create cascade delete action on those relations. However two cascade deletions will be applied on the same table which is not allowed.
To correct this issue, you have two solutions:
Make one of the foreign key property Nullable<int> which by default not create a cascade delete action on that relationship.
Or you can disable cascade delete action by using Fluent API like this :
// Assuming that you want to disable cascade deletion with ToLocalization
modelBuilder.Entity<Passage>()
.HasRequired(p => p.ToLocalization)
.WithMany()
.WillCascadeOnDelete(false);
I have a 1 to many relationship between LabelLineItem and DespatchPart.
I can't understand why cascade delete is off for this relationship.
There is no relationship defined in the context using the fluent API.
There is no LabelLineItems navigation collection in DespatchPart, so there is no reference back to LabelLineItem.
public class LabelLineItem
{
public int Id { get; set; }
public int DespatchPartId { get; set; }
public int LabelConfigId { get; set; }
public string Content { get; set; }
// Navigation
public virtual LabelConfig LabelConfig { get; set; }
public virtual DespatchPart DespatchPart { get; set; }
}
public class DespatchPart
{
public int Id { get; set; }
public int DespatchId { get; set; }
// Navigation
public virtual Despatch Despatch { get; set; }
//...
}
It's my understanding that one-to-many relationships default to cascade delete on. As demonstrated in the code sample above.
Whereas zero-or-one-to-many relationships default to cascade delete off as would be the case if either:
- DespatchPartId was declared as int?,
- The fluent API declared the relationship as optional i.e. DespatchPart.HasMany(p => p.LabelLineItems).WithOptional(i => i.DespatchPart).
But neither of these are the case which is why I'm confused.
FYI -
I'm certain the cascade is off, because when I tested the cascade delete by removing a despatch part record (in SQLManagementStudio), I received an attempted FK violation in the LableLineItem table as I tried to remove a referenced DespatchPart record. This wouldn't have occurred if it the delete had cascaded to the LabelLineItem table.
I have a property on my items class called vend_id which of course EF thinks is a foreign key to the vendor table. It actually should be a foreign key in the database but for reasons unknown to me the designers of the db chose not to make it a foreign key.
I am using EF to create a copy of the db schema on the local machine. When EF creates the database I want to tell it not to create a foreign key on the vend_id column. How do I do that? Ideally I do not want to rename the property because there are several such instances in my db and it just makes it confusing.
Thank you,
Sam
You can't have a navigation property to a Vendor entity in your Item entity class if the Items table does not have a foreign key to table Vendor. If you did not specify a navigation property in entity class Item, EF would not infer that vend_id is a foreign key.
Update:
Unable to reproduce with the following:
[Table("EntityA")]
public partial class EntityA
{
public int Id { get; set; }
public Nullable<int> EntityBId { get; set; }
public string Description { get; set; }
[ForeignKey( "EntityBId" )]
public virtual EntityB EntityB { get; set; }
// this is not created as a FK
// nor does EntityCId cause a FK
public int EntityC_Id { get; set; }
}
[Table("EntityC")]
public class EntityC
{
public EntityC()
{
EntitiesD = new HashSet<EntityD>();
}
public int EntityCId { get; set; }
public string Name { get; set; }
public virtual ICollection<EntityD> EntitiesD { get; set; }
}
I have one to one relationship with foreign keys but the Cascade Delete is not enabled for some reason. The sample code is below.
public class AppRegistration
{
public int AppRegistrationId { get; set; }
[Required]
[StringLength(50)]
[Display(Name = "Username")]
public string UserName { get; set; }
[Required]
[StringLength(100)]
public string Password { get; set; }
[StringLength(20)]
public string StudentOrAgent { get; set; }
// navigation properties
public virtual AppStatus AppStatus { get; set; }
public virtual Agreement Agreement { get; set; }
public virtual AnotherTable AnotherTable { get; set; }
}
The dependent table with a foreign key is below.
public class Agreement
{
[Key]
[ForeignKey("AppRegistration")]
public int AppRegistrationId { get; set; }
public DateTime DateAgreed { get; set; }
public virtual AppRegistration AppRegistration { get; set; }
}
When I try to delete an entry from the generated AppRegistrations table I get a Reference constraint conflict.
I tried putting [Required] on the navigation property in the dependent table but it doesn't do anything - the Update-Database command shows the No pending code-based migrations. message. Any ideas? Thanks.
Update:
I'm getting the following error message:
The DELETE statement conflicted with the REFERENCE constraint "FK_dbo.AppStatus_dbo.AppRegistrations_AppRegistrationId". The conflict occurred in database "MVCapp", table "dbo.AppStatus", column 'AppRegistrationId'.
I decided to work out the cascade delete problem in a separate sample project. I found the following blog & MSDN pages very useful.
http://blog.bennymichielsen.be/2011/06/02/entity-framework-4-1-one-to-one-mapping/
http://msdn.microsoft.com/en-us/library/gg671256%28v=VS.103%29.aspx
http://msdn.microsoft.com/en-us/library/gg671273%28v=VS.103%29.aspx
Using the Code First approach create the following Model.
public class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
public virtual Book Book { get; set; }
}
public class Book
{
public int CategoryId { get; set; }
public string BookTitle { get; set; }
public string BookAuthor { get; set; }
public string BookISBN { get; set; }
public virtual Category Category { get; set; }
}
(I realize the entity names suggest one-to-many relationship, but I am trying to model 1-to-1 relationship, as in my original question at the top.)
So, in the above model each Category can only have one Book.
In your DbContext-derived class add the following.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Entity<Book>()
.HasKey(t => t.CategoryId);
modelBuilder.Entity<Category>()
.HasRequired(t => t.Book)
.WithRequiredPrincipal(t => t.Category)
.WillCascadeOnDelete(true);
}
(The following namespaces are required for the above code: System.Data.Entity, System.Data.Entity.ModelConfiguration.Conventions.)
This properly creates the 1-to-1 relationship. You'll have a primary key in each table and also a foreign key in Book table with ON DELETE CASCADE enabled.
In the above code, on the Category entity I used WithRequiredPrincipal() with t => t.Category argument, where the argument is the foreign key column in the dependent table.
If you use WithRequiredPrincipal() without an argument you'll get an extra column in the Book table and you'll have two foreign keys in the Book table pointing to CategoryId in Category table.
I hope this info helps.
UPDATE
Later on I found answer directly here:
http://msdn.microsoft.com/en-us/data/jj591620#RequiredToRequired
A reason why you're not getting cascading delete is because your relationship is optional.
If you want the relationship required i.e. an AppRegistration has to have one Agreement you can use (cascading delete configured automatically):
public class Agreement
{
...
[Required]
public AppRegistration AppRegistration{ get; set; }
}
If you want the relationship to be optional with cascading delete you can configure this using Fluent API:
modelBuilder.Entity<AppRegistration>()
.HasOptional(a => a.Agreement)
.WithOptionalDependent()
.WillCascadeOnDelete(true);
When performing a delete of a one-many relationship without exposing the foreign key, EF deletes the parent record and tries to null the foreign key on the child records. This of course causes an error because the foreign key is not nullable. Adding the foreign key to the child class overrides this behavior, but I'd rather not expose it.
For example given the following two classes, I'd prefer not to have JobId as a property of the Project class.
public class Job : ModelBase
{
[Required]
[StringLength(100)]
public string Company { get; set; }
[Required]
[StringLength(100)]
public string JobTitle { get; set; }
public ICollection<Project> Projects { get; set; }
}
public class Project : ModelBase
{
[Required]
[StringLength(100)]
public string Name { get; set; }
[Required]
public string Summary { get; set; }
public int JobId { get; set; }
}
Is there a way to enable cascading deletes in EF Code First without exposing the foreign key on the many side of the relationship?
Yup! Remove JobId and add the following:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Job>().HasMany(j => j.Projects).WithRequired();
}
In the database, this will add a cascading delete in the PK/FK relationship.
(I'm assuming that your ModelBase has an integer Id =)