I get an error in the comments model in relations, I'm waiting for a practical answer, it seems like there is nothing difficult. I use the picture model easily in the article model. I thought of using this table in the auhor model, but I am stuck in relationships, what should I do?
public class Article
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Detail { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
public bool IsActive { get; set; } = false;
// Scaler properties
public int AuthorId { get; set; }
public int CategoryId { get; set; }
// Navigation properties
public virtual Picture Picture { get; set; } = new Picture();
public virtual Author Author { get; set; } = new Author();
public virtual Category Category { get; set; } = new Category();
public virtual ICollection<Comment>? Comments { get; set; }
}
public class Author
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Surname { get; set; } = string.Empty;
public string EMail { get; set; } = string.Empty;
public string Password { get; set; } = string.Empty;
public DateTime DateOfBirth { get; set; }
public DateTime CreatedAt { get; set; }
// Navigation properties
public virtual ICollection<Article>? Articles { get; set; }
public virtual ICollection<Comment>? Comments { get; set; }
}
public class Category
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public byte SortBy { get; set; }
// Navigation property
public virtual ICollection<Article>? Articles { get; set; }
}
public class Comment
{
public int Id { get; set; }
public string Content { get; set; } = string.Empty;
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; } = false;
// Scaler properties
public int ArticleId { get; set; }
public int AuthorId { get; set; }
// Navigation properties
public virtual Article Article { get; set; } = new Article();
public virtual Author Author { get; set; } = new Author();
}
public class Picture
{
public int Id { get; set; }
public string Src { get; set; } = string.Empty;
public string Alt { get; set; } = string.Empty;
public string? Title { get; set; }
// Scaler property
public int ArticleId { get; set; }
// Navigation property
public virtual Article Article { get; set; } = new Article();
}
This is the error:
Introducing FOREIGN KEY constraint 'FK_Comments_Authors_AuthorId' on
table 'Comments' 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
Are there any problems in other relationships? we can discuss
Related
I have a problem and it is that when I load a navigation property of an entity, it loads the other navigation properties of the property that I am loading, which generates me as a loop.
Company.cs
public class Company
{
[Key]
public int Id { get; set; }
public int UserId { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string EmailPassword { get; set; }
public int EmailType { get; set; }
public string Description { get; set; }
public DateTime CreationDate { get; set; }
public bool IsActive { get; set; } = true;
public User User { get; set; }
public List<CompanySpecialty> CompanySpecialties { get; } = new List<CompanySpecialty>();
public List<CompanySchedule> CompanySchedules { get; } = new List<CompanySchedule>();
}
CompanySpecialty.cs
public class CompanySpecialty
{
[Key]
public int Id { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
public string Description { get; set; }
public double Cost { get; set; }
public int DurationInMinutes { get; set; }
public bool IsActive { get; set; } = true;
}
I have these entities, the problem occurs when in the entity Company I try to load the property CompanySpecialties since the property company specialties loads the property Company that it owns, and it is property ** Company** reloads the property CompanySpecialties and so on.
What I want is to know how to load only once and not load recursively.
I wait an answer. Thanks.
I'm doing a project using ASP.NET Core MVC. I created my models and when I update the migration I got this error.
Introducing FOREIGN KEY constraint 'FK_Branch_Countries_CountriesId' on table 'Branch' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints
I went through the code and I hope there is nothing wrong with the foreign key assigned.
I hope the issue is Branch and Country both contain the CountryId for the foreign key. It should be connected to both tables connected with the Country table. But here it says can't create the table because of the cycle or multiple cascade paths.
So how to avoid this and do the migrations? Or the way I connected 3 tables are wrong?
Could you help me with this?
public class Countries
{
[Key]
public int Id { get; set; }
[Required]
public string Country_Name { get; set; }
public string Country_Code { get; set; }
public string Note { get; set; } = "N/A";
public bool Status { get; set; } = true;
public DateTime CreatedDate { get; set; } = DateTime.Now;
public int CreateBy { get; set; }
public DateTime ModifiedDate { get; set; } = DateTime.Now;
public int ModifiedBy { get; set; }
public virtual IList<Province> Province { get; set; }
public virtual IList<Branch> Branch { get; set; }
public Countries()
{
Province = new List<Province>();
Branch = new List<Branch>();
}
}
public class Province
{
[Key]
public int Id { get; set; }
[Required]
public string Province_Name { get; set; }
public string Province_Code { get; set; }
[Required]
[ForeignKey("Countries")]
public int Country_Id { get; set; }
public virtual Countries Countries { get; set; }
public string Note { get; set; } = "N/A";
public bool Status { get; set; } = true;
public DateTime CreatedDate { get; set; } = DateTime.Now;
public int CreateBy { get; set; }
public DateTime ModifiedDate { get; set; } = DateTime.Now;
public int ModifiedBy { get; set; }
public virtual IList<Cities> Cities { get; set; }
public virtual IList<Branch> Branch { get; set; }
public Province()
{
Cities = new List<Cities>();
Branch = new List<Branch>();
}
}
public class Cities
{
[Key]
public int Id { get; set; }
public string City_Name { get; set; }
[ForeignKey("Province")]
public int Province_Id { get; set; }
public virtual Province Province { get; set; }
public string Postal_Code { get; set; }
public string Istat_Code { get; set; }
public string Note { get; set; } = "N/A";
public bool Status { get; set; } = true;
public DateTime CreatedDate { get; set; } = DateTime.Now;
public int CreateBy { get; set; }
public DateTime ModifiedDate { get; set; } = DateTime.Now;
public int ModifiedBy { get; set; }
public virtual IList<Branch> Branch { get; set; }
public Cities()
{
Branch = new List<Branch>();
}
}
public class Branch
{
[Key]
public int Id { get; set; }
public string BranchName { get; set; }
public string Note { get; set; }
public int City_Id { get; set; }
public virtual Cities Cities { get; set; }
public int Province_Id { get; set; }
public virtual Province Province { get; set; }
public int Country_Id { get; set; }
public virtual Countries Countries { get; set; }
public string LocationEmailAddress { get; set; }
public string LocationContactNumber { get; set; }
public bool Status { get; set; } = true;
public DateTime CreatedDate { get; set; } = DateTime.Now;
public int CreateBy { get; set; }
public DateTime ModifiedDate { get; set; } = DateTime.Now;
public int ModifiedBy { get; set; }
public virtual IList<EmployeeLocations> EmployeeLocations { get; set; }
public Branch()
{
EmployeeLocations = new List<EmployeeLocations>();
}
}
It was caused by multiple cascade paths:
Branch-Country-Province-City
Branch-Province-City
Branch-City
You could check this case for more details:Foreign key constraint may cause cycles or multiple cascade paths?
Solution is very simple. You should remove ContryId from Branch, because ContryId is already referenced in Province.
For example, I have the following infrastructure class:
[Table("GeoHistory")]
public partial class GeoHistory
{
public int Id { get; set; }
public int CompanyId { get; set; }
public int DriverId { get; set; }
[StringLength(50)]
public string Name { get; set; }
public string Description { get; set; }
[StringLength(100)]
public string GeofenceLocation { get; set; }
[StringLength(100)]
public string GeofencePrevious { get; set; }
[StringLength(20)]
public string StateLocation { get; set; }
[StringLength(20)]
public string StatePrevious { get; set; }
public DateTime? DateTime { get; set; }
[StringLength(5)]
public string Heading { get; set; }
public decimal? Speed { get; set; }
[StringLength(50)]
public string Status { get; set; }
}
and the following View class (let's forget about domain layer):
public class GeoHistoryViewModel
{
public int Id { get; set; }
public int? CompanyId { get; set; }
public int? DriverId { get; set; }
[StringLength(50)]
public string Name { get; set; }
public string Description { get; set; }
}
as we can see, we edit only part of field list.
Now, we want to update data in DB. Of course, we can write like:
Infrastructure.Main.GeoHistory geoHistory = db.GeoHistories.Find(id);
geoHistory.CompanyId = model.CompanyId;
geoHistory.DriverId = model.DriverId;
geoHistory.Name = model.Name;
........
db.SaveChanges();
It works. But I want to use Automapper. And if I try to do the following:
Infrastructure.Main.GeoHistory geoHistory = mapper.Map<Infrastructure.Main.GeoHistory>(model);
db.GeoHistories.Attach(geoHistory);
db.Entry(geoHistory).State = EntityState.Modified;
db.SaveChanges();
It works, but of course remove values of fields, which are not exist in View Model, but exist in infrastructure class. How to use automapper, but don't lost these fields?
I will appreciate if somebody can tell me why entity framework is not creating join table for following model. It is creating table for type and feature but not the table that will join them.
public class DeviceType
{
[Display(Name = "ID")]
public int DeviceTypeID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<DeviceFeature> DeviceFeatures { get; set; }
}
public class DeviceFeature
{
[Display(Name = "ID")]
public int DeviceFeatureID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public IEnumerable<DeviceType> DeviceTypes { get; set; }
}
public class DeviceFeatureView
{
public virtual IEnumerable<DeviceType> DeviceTypes { get; set; }
public virtual IEnumerable<DeviceFeature> DeviceFeatures { get; set;
}
You do not need the bridge to create a many-to-many relationship. EF will figure it out. Change the type of the navigation properties from IEnumerable to ICollection like this:
public class DeviceType
{
public DeviceType()
{
this.DeviceFeatures = new HashSet<DeviceFeature>();
}
[Display(Name = "ID")]
public int DeviceTypeID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<DeviceFeature> DeviceFeatures { get; set; }
}
public class DeviceFeature
{
public DeviceFeature()
{
this.DeviceTypes = new HashSet<DeviceType>();
}
[Display(Name = "ID")]
public int DeviceFeatureID { get; set; }
[Required]
public string Name { get; set; }
public string Description { get; set; }
public ICollection<DeviceType> DeviceTypes { get; set; }
}
More about it here.
I have a database with 3 tables:
Subjects
Members
Topics
Then I added the connection string to web.config and created an EF with the following classes:
namespace MySite.Models
{
public class MySiteDBModel : DbContext
{
public DbSet<Topic> Topics { get; set; }
public DbSet<Subject> Subjects { get; set; }
public DbSet<Member> Members { get; set; }
public DbSet<TopicDataModel> TopicDataModel { get; set; }
protected override void OnModelCreating(DbModelBuilder mb)
{
mb.Conventions.Remove<PluralizingTableNameConvention>();
}
}
public class Topic
{
[Key]
public int TopicID { get; set; }
public int SubID { get; set; }
public int MemberID { get; set; }
public string TDate { get; set; }
public string Title { get; set; }
public string FileName { get; set; }
public int Displays { get; set; }
public string Description { get; set; }
public virtual Subject Subject { get; set; }
public virtual Member Member { get; set; }
public virtual ICollection<TopicView> TopicView { get; set; }
}
public class Subject
{
[Key]
public int SubID { get; set; }
public string SubName { get; set; }
public virtual ICollection<Topic> Topic { get; set; }
}
public class Member
{
[Key]
public int MemberID { get; set; }
public string FLName { get; set; }
public string Email { get; set; }
public string Pwd { get; set; }
public string About { get; set; }
public string Photo { get; set; }
public virtual ICollection<Topic> Topic { get; set; }
}
public class TopicDataModel
{
[Key]
public int TopicID { get; set; }
public string SubName { get; set; }
public string FLName { get; set; }
public string TDate { get; set; }
public string Title { get; set; }
public int Displays { get; set; }
public string Description { get; set; }
}
}
Now when I am trying to query the database with the this code:
public ActionResult Index()
{
var topics = from t in db.Topics
join s in db.Subjects on t.SubID equals s.SubID
join m in db.Members on t.MemberID equals m.MemberID
select new TopicDataModel()
{
TopicID = t.TopicID,
SubName = s.SubName,
FLName = m.FLName,
TDate = t.TDate,
Title = t.Title,
Displays = t.Displays,
Description = t.Description
};
return View(topics.ToList());
}
I got this Error:
The model backing the 'MySiteDBModel' context has changed since the
database was created. Either manually delete/update the database, or
call Database.SetInitializer with an IDatabaseInitializer instance.
For example, the DropCreateDatabaseIfModelChanges strategy will
automatically delete and recreate the database, and optionally seed it
with new data.
Please help me!!!!!!
You need to set some controls on how EF is handling changes to your data model. Julie Lerman has a good blog post on Turning Off Code First Database Initialization Completely.
Also, here is a good overview - Inside Code First Database Initialization