Entity Framework Code First: Entity Splitting - frameworks

Is it possible to map the following scenario?
Data Tables
Students
+ ID: int PK
+ Name: varchar(200)
Classes
+ ID: int PK
+ StudentID: FK
+ CourseID: FK
+ EnrollmentDate: DateTime
Courses
+ ID: int PK
+ Name: varchar(200)
I would like to map the tables to entities below.
public class Student
{
[Key]
public int ID {get;set;}
public string Name {get;set;}
public virtual ICollection<Class> Classes {get;set;}
}
public class Class
{
[Key]
public int ID {get;set;}
public Student Student {get;set;}
public DateTime EnrollmentDate {get;set;}
public string Name {get;set;} // this comes from the Courses data table
}

This should be how to establish the FK relationships you require:
public class Student
{
[Key]
public int StudentId {get;set;}
public string Name {get;set;}
}
public class Class
{
[Key]
public int ClassId {get;set;}
public DateTime EnrollmentDate {get;set;}
//foreign keys
public int CourseId {get;set;}
public string StudentId {get;set;}
//virtual constraint to link to referenced tables
public virtual Course Course {get;set;}
public virtual Student Student {get;set;}
}
public class Course
{
[Key]
public int CourseId {get;set;}
public string CourseName {get;set;}
}

Related

EF Core navigation property without relations(foreign-key)

I have three classes
public class Country
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public byte CountryID { get; set; }
public byte OfficialLangID { get; set; }
}
public class Language
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public byte LangID { get; set; }
}
public class Name
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public byte NameID { get; set; }
public bool isLanguage { get; set; } // true for language - false for country
public byte FK { get; set; } // FK=LangID or CountryID
}
Now I want to create Navigation properties:
Country.Name
Language.Name
Name.Language
Name.Country
I want to do it in this way for many reasons, one of them to search for all the names in one table without joining.
Please don't suggest another way,I want navigation properties for my way.
why you're doing it like this? putting a boolean field to check the type of the entity here doesn't make any sense? in the end, the ef framework will create 2 tables.
here is my approach:
public class Country
{
public byte Id {get;set;}
public string Name {get;set;}
public int LanguageId {get;set;}
}
public class Language
{
public byte Id {get;set;}
public string Name {get;set;}
// assuming that each language may have one or many countries
public ICollection<Country> Countries {get;set;}
}
ef core here will create the tables and the relations automatically. now if you see some code duplications (like I've understood), that the 2 entities use the same field types and names, here is what you can do
public abstract class EntityBase
{
public byte Id {get;set;}
public string Name {get;set;}
}
now inherit this abstract class to the entity class
public class Country : EntityBase
{
public int LanguageId {get;set;}
}
public class Language : EntityBase
{
public ICollection<Country> Countries {get;set;}
}

EntityFramework 6 One To One Mapping with shared key

As an example I had following existing table, which i cannot change
Contacts - [ID, Name, Age] (Primary Key: ID)
No i want to extend the functionality using following extension table
Details - [ID, Address, Phone] (Primary Key:ID, Foreign Key: ID)
Note that Details.Id is primary key as well as foreign key (referencing Contacts.Id)
My domain model is
Contact
{
public int Id {get;set;}
public string Name {get;set;}
public int Age {get;set;}
public Details Details {get;set;}
}
Details
{
public int Id {get;set;}
public string Address {get;set;}
public string Phone {get;set;}
}
How do i write mapping for this in entity framework 6
You can use composite key this way:
public class Details
{
[Key, ForeignKey("Contact")]
public int Id { get; set; }
public string Address { get; set; }
public string Phone { get; set; }
public Contact Contact { get; set; }
}
public class Contact
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public Details Details { get; set; }
}
Now Details's ID is a primary key as well as foreign key

EF Code First Multiple Tables to single entity

I'm just starting out with Entity Framework and I seem to be misunderstanding something. Basically I've got a database already setup. Let's say the following are my tables.
**Employees**
EmployeeId
CubeId (FK to Cubes table)
NameId (FK to Name table)
**Cubes**
CubeId
CubeName
**Person**
NameId
FirstName
LastName
I want to be able to write something like this: SELECT EmployeeId, CubeId, CubeName, FirstName, LastName FROM Employees LEFT OUTER JOIN Cubes LEFT OUTER JOIN Person. So it would return all of the Employees. Basically, in EF Code First do you have to create a class for EVERY table? If not, how do you create a LEFT OUTER Join equivalent? All of the examples I've found use navigational properties to go from table to table (i.e. class to class).
Models:
public class Employee
{
[Key]
public int EmployeeId {get;set;}
public int CubeId {get;set;}
[ForeignKey("Cube")]
public int NameId {get;set;}
[ForeignKey("Name")]
public virtual Cube Cube {get;set;}
public virtual Name Name {get;set;}
}
public class Cube
{
[Key]
public int CubeId {get;set;}
public string CubeName {get;set;}
}
public class Name
{
[Key]
public int NameId {get;set}
public string FirstName {get;set;}
public string LastName {get;set;}
}
Your context:
public class YourContext:DbContext
{
public DbSet<Name> Names {get;set;}
public DbSet<Cube> Cubes {get;set;}
public DbSet<Employee> Employees {get;set;}
}
Your query:
YourContext db = new YourContext();
var query = db.Employees.Where(x => x.EmployeeId == id).Select(x => new
{
EmployeeId = x.EmployeeId,
CubeId = x.Cube.CubeId,
CubeName = x.Cube.CubeName,
FirstName = x.Name.FirstName,
LastName = x.Name.LastName
}).FirstOrDefault();
This will locate first employee that has some id (or return null if there's none), and then create a type that has all the properties you mentioned. If you need last name, you access it with:
string lastName = query.LastName;

Having a difficulty with EF Fluent API

I have 4 tables that like thus:
public class Table1
{
public int Id {get;set;}
public string Name {get;set;}
}
public class Table2
{
public int Id {get;set;}
public string Name {get;set;}
public int Table1Id {get;set;}
public virtual Table1 {get; set;}
}
public class Table3
{
public int Id {get;set;}
public string Name {get;set;}
public int Table2Id {get;set;}
public virtual Table2 {get; set;}
}
public class Table4
{
public int Id {get;set;}
public string Name {get;set;}
public int Table3Id {get;set;}
public virtual Table3 {get; set;}
}
And my fluent API is like thus:
modelBuilder.Entity<Table2>().HasRequired(x => x.Table1).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<Table3>().HasRequired(x => x.Table2).WithMany().WillCascadeOnDelete(false);
modelBuilder.Entity<Table4>().HasRequired(x => x.Table3).WithMany().WillCascadeOnDelete(false);
When I try to seed the tables, I get this error:
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_Table4_Table3_Table3Id.
The conflict occurred in database MyDb, table "dbo.Table3", column 'Id'.The statement has been terminated."
I cannot see where I am going wrong
do this...
modelBuilder.Entity<Table2>()
.HasRequired(t => t.Table1)
.WithMany() // t => t.AllTable2s)
.HasForeignKey(t => t.Table1ID);
...and above all make it compile ! :) (e.g. public virtual Table1 {get; set;} into public virtual Table1 Table1 {get; set;}

Entity Framework 4 code-only reference column name

I created classes:
public class Country
{
public long CountryId {get;set;}
public string CountryName {get;set;}
}
public class Profile
{
public long ProfileId {get;set;}
public string ProfileName {get;set;}
public Country Country {get;set;}
}
and configuration for Profile:
public class ProfileConfiguration : EntityConfiguration<Profile>
{
public IlluminatiCoreProfileConfiguration()
{
Relation(p => p.Country);
}
}
Then I create context and run context.CreateDatabase(). New database contains table Profiles with column Country_CountryId. How can I write configuration for changing column name to "CountryId"?
Thanks.
In your POCO for Profile:
public class Profile
{
public long ProfileId {get;set;}
public string ProfileName {get;set;}
[ForeignKey("CountryId")]
public Country Country {get;set;}
}
In your POCO for Country
[Table("Country")]
public class Country
{
[Column(Name = "CountryId")]
public int CountryId {get;set;}
}
This will over write the brain dead Object_Property mapping that EF by default creates. You can specify this on any table / property to override the actual DB column naming conventions.
EDIT:
I guess the namespace for those annotations would be helpful:
using System.ComponentModel.DataAnnotations;