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

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'.

Related

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

EF Core More Navigation properties from two tables

I am trying to create navigation properties for two table.
Here is the code.
public class CourseMaster
{
public int Id { get; set; }
public string Name { get; set; }
public int? TeamLeaderId { get; set; }
[ForeignKey("TeamLeaderId")]
public StudentMaster TeamLeader { get; set; }
public int? GroupLeaderId { get; set; }
[ForeignKey("GroupLeaderId")]
public StudentMaster GroupLeader { get; set; }
public virtual ICollection<StudentMaster> Students { get; set; }
}
public class StudentMaster
{
public int id { get; set; }
public string Name { get; set; }
public int FirstSemCourseId { get; set; }
[ForeignKey("FirstSemCourseId")]
public CourseMaster FirstSemCourse { get; set; }
public int SecondSemCourseId { get; set; }
[ForeignKey("SecondSemCourseId")]
public CourseMaster SecondSemCourse { get; set; }
public int ThirdSemCourseId { get; set; }
[ForeignKey("ThirdSemCourseId")]
public CourseMaster ThirdSemCourse { get; set; }
public int CourseMasterId { get; set; }
public CourseMaster Course { get; set; }
}
// Fluent API
modelBuilder.Entity<StudentMaster>()
.HasOne(p => p.Course)
.WithMany(b => b.Students)
.HasForeignKey(p => p.CourseMasterId);
But when i am creating migrations i am getting following error.
Unable to determine the relationship represented by navigation property 'CourseMaster.TeamLeader' of the type 'StudentMaster'. Either manually configure the relationship, or ignore this property from model.
Whether the procedure i am following is right or should i create intermediate class.
or how should i create class.
Any help are appreciated.
Thanks

EF code first model not in sync with database

My EF Code First model for some reason is not in sync with the db. I'm getting this error:
{"Invalid column name 'Type_Id1'."}
The field is actually called 'Type_Id' so I'm not sure from where that 1 comes up. I have the table column called as Type_Id and also I've added a Type_Id in my type entity model.
Why might I be getting that error message, plus why I'm getting 1 at the end of the name?
Update
My Task class:
public class Task
{
public Task()
{
Language = 1;
Grades = new HashSet<Grade>();
Categories = new HashSet<Category>();
Subjects = new HashSet<Subject>();
Rooms = new Collection<Room>();
Tools = new Collection<Tool>();
}
[Key]
public int Id { get; set; }
public string Description { get; set; }
public virtual TaskType Type { get; set; }
public string Rules { get; set; }
[Required]
[StringLength(200), MinLength(1)]
public string Name { get; set; }
public int PreperationTime { get; set; }
public int InstructionTime { get; set; }
public int TaskTime { get; set; }
public int Type_Id { get; set; }
public string VideoLink { get; set; }
[Required]
public int Language { get; set; }
public int? MinimumParticipants { get; set; }
public int? MaximumParticipants { get; set; }
public int? Rating { get; set; }
[Required]
public string CreatedBy { get; set; }
public virtual ICollection<Grade> Grades { get; set; }
public virtual ICollection<Category> Categories { get; set; }
public virtual ICollection<Subject> Subjects { get; set; }
public virtual ICollection<Room> Rooms { get; set; }
public virtual ICollection<Tool> Tools { get; set; }
}
DBContext class:
public ApplicationDbContext() : base("DefaultConnection", false)
{
}
public DbSet<Task> Tasks { get; set; }
public DbSet<TaskType> TaskTypes { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
You need to add the FK attribute on your navigation property. EF is creating Type_Id1 because Type_Id already exists (although it can't tell by convention it is the FK).
[ForeignKey("Type_Id")]
public virtual TaskType Type { get; set; }
https://msdn.microsoft.com/en-us/data/jj591583.aspx#Relationships

EF Code First 6 and many-to-many with entity mapping

Following the example in this question: How to create a many-to-many mapping in Entity Framework? I would like to have a table mapping where I can add or remove many-to-many relationships without having to go through the Media or Contract entities.
Essentially, I would like to have:
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<Media> Medias { get; set; }
}
public class ContractMedia // Association table implemented as entity
{
public Media Media { get; set; }
public int MediaId { get; set; }
public Contract Contract { get; set; }
public int ContractId { get; set; }
}
Is it possible to configure this scenario using the FluentAPI?
afaik not with the ContractMedia entity, but you can:
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<ContractMedia> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<ContractMedia> Medias { get; set; }
}
public class ContractMedia // Association table implemented as entity
{
public Media Media { get; set; }
public int MediaId { get; set; }
public Contract Contract { get; set; }
public int ContractId { get; set; }
}
or
public class Media // One entity table
{
public int Id { get; set; }
public string Name { get; set; }
public bool Enabled { get; set; }
public virtual ICollection<Contract> Contracts { get; set; }
}
public class Contract // Second entity table
{
public int Id { get; set; }
public string Code { get; set }
public virtual ICollection<Media> Medias { get; set; }
}
that will lead to the creation of a non mapped association table in the database.

Entity Framework : get related entities

I created a WCF service with Entity Framework.
I have 2 tables : Theaters and Locality. Locality as a foreign key in Theaters.
My method :
public theater[] GetTheaters()
{
using (Entities context = new Entities())
{
return context.theater.ToArray();
}
}
I have to remove the "virtual" keyword from "public virtual locality locality { get; set; }" in my theater class. Otherwise, I get a CommunicationException.
But when I do that, I get my list of theaters but the locality is null...
How can I get the locality ?
Thanks
My model class ( I also have other entities) :
public partial class locality
{
public locality()
{
this.theater = new HashSet<theater>();
}
public int idLocality { get; set; }
public int npa { get; set; }
public string locality1 { get; set; }
public ICollection<theater> theater { get; set; }
}
public partial class theater
{
public theater()
{
this.session = new HashSet<session>();
}
public int idTheater { get; set; }
public string name { get; set; }
public string address { get; set; }
public int idLocality { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public int seats { get; set; }
public string phone { get; set; }
public string email { get; set; }
public bool threeD { get; set; }
public locality locality { get; set; }
public ICollection<session> session { get; set; }
}
Here is the error that I get :
"Object graph for type 'locality' contains cycles and cannot be serialized if reference tracking is disabled.
EDIT :
The solution that I found :
In my locality class, I had a Collection of theaters.
I had to add "private to the setter like this :
" public ICollection theater { get; private set; }"
So it works, but I still have a problem, I can't access to the theaters from the locality entity anymore. (no more bi-directional)
If you want to force related entities to load, you can use the Include method to do so. By default, related entities are loaded Lazily.
Your example would be:
public theater[] GetTheaters()
{
using (Entities context = new Entities())
{
return context.theater.Include(t=>t.Locality).ToArray();
}
}
You can use eager loading or explicit loading. With eager loading you use the Include extension method:
return context.Theater.Include(t => t.Locality).ToArray();
You're missing the correct annotations to create the relationships. See the code below. (or create the relationships yourself if using the FluentAPI)
Look for the [Key] and [ForeignKey] annotations, as well as the virtual keyword.
public partial class locality
{
public locality()
{
//this.theater = new HashSet<theater>();
}
[Key]
public int idLocality { get; set; }
public int npa { get; set; }
public string locality1 { get; set; }
public virtual ICollection<theater> theaters { get; set; }
}
public partial class theater
{
public theater()
{
//this.session = new HashSet<session>();
}
[Key]
public int idTheater { get; set; }
public string name { get; set; }
public string address { get; set; }
public int idLocality { get; set; }
public double latitude { get; set; }
public double longitude { get; set; }
public int seats { get; set; }
public string phone { get; set; }
public string email { get; set; }
public bool threeD { get; set; }
[ForeignKey("idLocality")]
public virtual locality locality { get; set; }
//public ICollection<session> session { get; set; }
}