Table Id field automatically append with table name that produce invalid column name - entity-framework

I have table Categories With Id column when insert occur is shows it shows errorSqlException: Invalid column name 'CategoriesId'.
public partial class Categories
{
public Categories()
{
CategoryTabs = new HashSet<CategoryTabs>();
}
public int Id { get; set; }
public string Title { get; set; }
public int? ParentId { get; set; }
public int? SeasonId { get; set; }
public int? Levels { get; set; }
public string Image { get; set; }
public string Description { get; set; }
public virtual Seasons Season { get; set; }
public List<Categories> children { get; set; }
public virtual ICollection<CategoryTabs> CategoryTabs { get; set; }
}
public partial class CategoryTabs
{
public int Id { get; set; }
public int? CategoryId { get; set; }
public int? TabId { get; set; }
public virtual Categories Category { get; set; }
public virtual Tabs Tab { get; set; }
}

CategoriesId is the conventional name for the Foreign Key property/column associated with the one-to-many self relationship introduced by
public List<Categories> children { get; set; }
collection navigation property inside Categories entity.
Looking at the entity model, most likely the idea was to use the ParentId for that purpose. Since it doesn't match EF Core naming conventions, it has to be mapped explicitly by using either ForeignKey data annotation:
[ForeignKey(nameof(ParentId))]
public List<Categories> children { get; set; }
or fluent API inside OnModelCreating override:
modelBuilder.Entity<Categories>()
.HasMany(e => e.children)
.WithOne()
.HasForeignKey(e => e.ParentId);

Related

Entity Framework Db context issue in .net core related to Models

Am Trying to create Two Tables like bellow got some EF error.
public class Student : ModelsBase
{
public string AdharNumber { get; set; }
public byte Religion { get; set; }
public int CategoryID { get; set; }
public string Cast { get; set; }
public string SubCast { get; set; }
public string Photo { get; set; }
public DateTime DateOfJoining { get; set; } = DateTime.Now;
[Required]
public ICollection<Address> TemporaryAddress { get; set; }
[Required]
public ICollection<Address> PermanentAddress { get; set; }
}
public class Address : ModelsBase
{
public string DoorNo { get; set; }
public string StreetLocality { get; set; }
public string Landmark { get; set; }
public string City { get; set; }
public int Taluk { get; set; }
public int District { get; set; }
public int State { get; set; }
public string Pincode { get; set; }
public bool IsPermanent { get; set; } = true;
public bool IsDefault { get; set; } = true;
[ForeignKey("Student")]
public Guid StudentId { get; set; }
}
Getting the bellow error while trying to Run the "Add-Migration command"
Both relationships between 'Address' and 'Student.PermanentAddress' and between 'Address' and 'Student.TemporaryAddress' could use {'StudentId'} as the foreign key. To resolve this, configure the foreign key properties explicitly in 'OnModelCreating' on at least one of the relationships
Please help. Thanks!
Your issue is that from the Address side of things you have a Many-to-1 with a single Student, but from the Student side of things you want 2x 1-to-Many relationships.
Since The relationship is really just a 1-to-Many from the student that you want to discriminate between temporary and permanent addresses:
public class Student : ModelsBase
{
public string AdharNumber { get; set; }
public byte Religion { get; set; }
public int CategoryID { get; set; }
public string Cast { get; set; }
public string SubCast { get; set; }
public string Photo { get; set; }
public DateTime DateOfJoining { get; set; } = DateTime.Now;
[Required]
public ICollection<Address> Addresses { get; set; } = new List<Address>();
[NotMapped]
public ICollection<Address> TemporaryAddresses => Addresses.Where(x => !x.IsPermanent).ToList();
[NotMapped]
public ICollection<Address> PermanentAddresses => Addresses.Where(x => x.IsPermanent).ToList();
}
With 1-to-many collections I recommend initializing them to an empty list to avoid null reference exceptions especially if lazy loading is disabled.
The caveat here is that from EF's perspective, Student only has the Addresses collection, do not attempt to use either TemporaryAddresses or PermanentAddresses in a query expression as these are unmapped accessors. If you want to filter based on a permanent address you will have to do it through Addresses and include the condition on IsPermanent in the query.
For example:
// Not valid...
var studentsInDetroit = context.Students.Where(x => x.PermanentAddresses.Any(a => a.City == "Detroit")).ToList();
// Valid...
var studentsInDetroit = context.Students.Where(x => x.Addresses.Any(a => a.IsPermanent && a.City == "Detroit")).ToList();
Normally I don't recommend using unmapped accessors in entities because of this. It is generally better to leave entities representing pure domain/data state and project that down to view models which can be more concerned about splitting the data into a more palatable form for consumption.

DbSet property of type class returns null

I'm creating an API for an app. The DbContext I have trouble with looks like this:
public class SchoolPlannerDbContext : DbContext
{
public SchoolPlannerDbContext(DbContextOptions<SchoolPlannerDbContext> options) : base(options) { }
public DbSet<Activity> Activities { get; set; }
public DbSet<Room> Rooms { get; set; }
public DbSet<Subject> Subjects { get; set; }
public DbSet<Teacher> Teachers { get; set; }
public DbSet<Group> Groups { get; set; }
}
The Activity class is as follows:
public class Activity
{
public int ID { get; set; }
[Required]
public Teacher Teacher { get; set; }
[Required]
public Room Room { get; set; }
[Required]
public Subject Subject { get; set; }
[Required]
public Group Group { get; set; }
[Required]
public int Slot { get; set; }
[Required]
public int Day { get; set; }
}
All the other properties contain an int ID and a string Name.
My controller looks like this:
public class SqlPlannerData : ISchoolPlannerData
{
private readonly SchoolPlannerDbContext db;
public SqlPlannerData(SchoolPlannerDbContext db)
{
this.db = db;
}
public IEnumerable<Activity> GetActivities()
{
return db.Activities;
}
public IEnumerable<Group> GetGroups()
{
return db.Groups;
}
}
GetGroups() works as intended and returns an IEnumerable with properties set correctly.
My problem is that when I'm trying to access db.Activities, the properties of type, say, Teacher (non-basic types like int) are set to null:
Debugger screenshot.
However, there is a row in the database that looks like this. I.e. the columns exist in the database.
What do I do to make GetActivities() return an IEnumerable with correctly set properties?
Some properties are null because of lazy loading you need to include them
return db.Activities
.Include(i => i.Teacher)
.Include(i => i.Room)
.Include(i => i.Subject)
.Include(i => i.Group)
.ToList()
Each propety Id can be configured by EF5+ as shadows. But I usually prefer to add all Ids explicitely. This way I have much less problem when I am using db context in the project. But is is optional and you can leave it as is
public class Activity
{
public int ID { get; set; }
[Required]
public int? TeacherId { get; set; }
[Required]
public int? RoomId { get; set; }
[Required]
public int? SubjectId { get; set; }
[Required]
public int? GroupId { get; set; }
public virtual Teacher Teacher { get; set; }
public virtual Room Room { get; set; }
public virtual Subject Subject { get; set; }
public virtual Group Group { get; set; }
[Required]
public int Slot { get; set; }
[Required]
public int Day { get; set; }
}
and in order to get list activities you have to add ToList() or ToArray() at least
public IEnumerable<Activity> GetActivities()
{
return db.Activities.ToArray();
}
and by the way, you can' t using not nullabe Id as required becaue it is relevant
[Required]
public int TeacherId { get; set; }
since int by default is 0 and it is a valid value and required will not be working

Two tables (One To Many) And table with many have (One To Zero Or One) with the table One

Two Tables One To Many
VehicleStatus {Id , LastVehicleStatusUpdateId}
VehicleStatusUpdated {Id, VehicleStatusId, IsResponse }
I need to make (one to zero or one) to last record in VehicleStatusUpdated ...
LastVehicleStatusUpdateId ==> Navigator To VehicleStatus
like This
How can i make it with Entity Framework Annotation ??!!
public class Vehicle : IEntity<int>
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
public string Number { get; set; }
public virtual VehicleStatus VehicleStatus { get; set; }
}
public class VehicleStatus : IEntity<int>
{
[ForeignKey("Vehicle")]
public int Id { get; set; }
public virtual Vehicle Vehicle { get; set; }
public int? LastVehicleStatusUpdateId { get; set; }
[ForeignKey("LastVehicleStatusUpdateId")]
public virtual VehicleStatusUpdate LastVehicleStatusUpdate { get; set; }
public virtual List<VehicleStatusUpdate> VehicleStatusUpdates { get; set;
}
public class VehicleStatusUpdate : IEntity<int>
{
[ForeignKey("LastVehicleStatus")]
public int Id { get; set; }
public DateTime UpdatedTime { get; set; }
public bool IsResponse { get; set; }
public int VehicleStatusId { get; set; }
[ForeignKey("VehicleStatusId")]
public virtual VehicleStatus VehicleStatus { get; set; }
}
I Tried this i got =>
Unable to determine the relationship represented by navigation property 'VehicleStatus.LastVehicleStatusUpdate' of type 'VehicleStatusUpdate'. Either manually configure the relationship, or ignore this property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

EF issues with 2 foreign keys going to same table

Using the new ASP.NET Core and Entity Framework 7.0 RC1 Final. I have two fields with a one-to-many relationship between Standards and Students. If I just have the one FK and Navigation Key the code works just fine, but when I add in the second FK (Standard2) and Nav field (Students2) I get the following error message:
InvalidOperationException: The navigation 'Students' on entity type 'TestProject.Models.Standard' has not been added to the model, or ignored, or target entityType ignored.
public class Standard
{
public Standard()
{
}
public int StandardId { get; set; }
public string StandardName { get; set; }
public IList<Student> Students { get; set; }
public IList<Student> Students2 { get; set; }
}
public Student()
{
}
public int StudentID { get; set; }
public string StudentName { get; set; }
public DateTime DateOfBirth { get; set; }
public byte[] Photo { get; set; }
public decimal Height { get; set; }
public float Weight { get; set; }
//Foreign key for Standard
public int StandardId { get; set; }
public int StandardId2 { get; set; }
[ForeignKey("StandardId")]
public Standard Standard { get; set; }
[ForeignKey("StandardId2")]
public Standard Standard2 { get; set; }
}
How do I have two FK's to the same table in EF 7?
The problem is that you need to specify the other end of your relationships by using InverseProperty attribute, something that EF cannot infer on its own and hence throws an exception:
public class Standard
{
public int StandardId { get; set; }
public string StandardName { get; set; }
[InverseProperty("Standard")]
public IList<Student> Students { get; set; }
[InverseProperty("Standard2")]
public IList<Student> Students2 { get; set; }
}
Or you can achieve the same results by using fluent API:
modelBuilder.Entity<Standard>()
.HasMany(s => s.Students)
.WithOne(s => s.Standard)
.HasForeignKey(s => s.StandardId);
modelBuilder.Entity<Standard>()
.HasMany(s => s.Students2)
.WithOne(s => s.Standard2)
.HasForeignKey(s => s.StandardId2);

Entity Framework Code first creates unexpected Tables and Relationships

Using EntityFramework 6.1.3, I've got the following
public class RacesContext:DbContext
{
public DbSet<Race> Races { get; set; }
public DbSet<Sailboat> Sailboats { get; set; }
public DbSet<VenueParticipation> VenueParticipations { get; set; }
}
public class Crew
{
public int CrewId { get; set; }
public string Name { get; set; }
}
public class Sailboat
{
[Key]
public int SailboatId { get; set; }
public string Name { get; set; }
public string Skipper { get; set; }
public virtual ICollection<Crew> BoatCrew { get; set; }
}
public class VenueParticipation
{
[Key]
public int Id { get; set; }
public virtual ICollection<Sailboat> Boats { get; set; }
public virtual ICollection<Race> Races { get; set; }
}
public class Race
{
[Key]
public int RaceId { get; set; }
public string Venue { get; set; }
public DateTime Occurs { get; set; }
}
EF creates the Creates the Crews table with the proper PK and FK as I would expect. But creates the Races Sailboats, VenueParticipations tables in an unexpected way. Sailboats get's the expected PK but the unexpected FK VenueParticipation_Id as does Races. I was expecting the VenueParticipations table to get FKs to the others allowing a many to many relationship.. I'm sure I'm missing something here. Any advice would be great.
You can either configure the joining tables VenueParticipationSailboat, VenueParticipationRace with the proper FKs or you can use the fluent API:
modelBuilder.Entity<VenueParticipation>()
.HasMany(t => t.Sailboats)
.WithMany(t => t.VenueParticipations)
.Map(m =>
{
m.ToTable("VenueParticipationSailboat");
m.MapLeftKey("VenueParticipationID");
m.MapRightKey("SailboatID");
});
https://msdn.microsoft.com/en-us/data/jj591620.aspx#ManyToMany