How to control the name of the foreign key relashionship object in EF Code First? - entity-framework

I have two entities in my EF Code first and they have a foreign key relationship.
public class Condition
{
public int Id { get; set; }
public string Name { get; set; }
public bool Active { get; set; }
}
public class ConditionGroup
{
public int Id { get; set; }
public Condition Condition { get; set; }
public int ConditionId { get; set; }
}
This is my entity map:
public class ConditionGroupMap : EntityTypeConfiguration<ConditionGroup>
{
public ConditionGroupMap()
{
this.ToTable("ConditionGroup");
this.HasKey(cg => cg.Id);
this.HasRequired(cg => cg.Condition).WithMany(c => c.ConditionGroups).HasForeignKey(cg => cg.ConditionId).WillCascadeOnDelete(true);
}
}
EF will create the a foreign key object in the database with the following Name:
ConditionGroup_Condition.
The problem is that this name collides with another object in the database for reasons which are beyond the scope of this question. So I would like to ask if there is a way to change this name?

Instead of doing it with the Fluent API, you could do it with Data Annotations:
public class ConditionGroup
{
public int Id { get; set; }
[ForeignKey("Condition")]
public int ConditionId { get; set; }
public Condition Condition { get; set; }
}
If that doesn't end up working you could always use the Column() Attribute to give it whatever column name you wished.

Related

How to join two model and display them in view in mvc 3.0 EF 5

I have two tables which have primary and foriegn key concept. I want to get the combined data on behalf of those keys. i don't know how to bind both the table into single model and display it into view.
Model
public class TVSerialModel
{
public Int32 Serial_ID { get; set; } // primary key
public string Serial_Name { get; set; }
public int? Release_Year { get; set; }
}
public class TVSerialEpisodeModel
{
public Int64 Video_ID { get; set; }
public Int32 Serial_ID { get; set; }// foriegn key
public string Episode_Name { get; set; }
public string Description { get; set; }
public DateTime Uploaded_Time { get; set; }
}
public class TVSerial_Episode_VM
{
public IEnumerable<TVSerialEpisodeModel> tvserialEpisode { get; set; }
public IEnumerable<TVSerialModel> Tvserial { get; set; }
}
Controller
public ActionResult NewEpisodeReleased()
{
cDBContext tvContext = new cDBContext();
TVSerial_Episode_VM tves=new TVSerial_Episode_VM();
tves= tvContext.dbTvSerialEpisodes.
Join(tvContext.dbTvSerials, p => p.Serial_ID, r => r.Serial_ID,(p, r) => new { p, r }).
Select(o => new TVSerial_Episode_VM
{ ****what should i write here to get all columns from both table**** }).
Take(9).ToList();
return View(tves);
}
Expected Result
If TVSerialEpisode has a property TVSerial, you can just dot through your foreign keys.
cDBContext.dbTvSerialEpisode
.Select(t =>
new {
t.TVSerial.Serial_ID,
t.TVSerial.Serial_Name,
t.Episode_Name
})
.Take(9)
.ToList();
You need to improve little bit the models you used with EF. You must include the reference object in model.
Like this
public virtual TVSerialModel TVSerialModel { get; set; }
in main table. This way you can select referred table too.
EF Include
public ActionResult NewEpisodeReleased()
{
cDBContext tvContext = new cDBContext();
TVSerial_Episode_VM tves=new TVSerial_Episode_VM();
tves= tvContext.dbTvSerialEpisodes.Include("TVSerialEpisodeModel")
.Include("TVSerialModel").ToList();
return View(tves);
}

EF 4.0 - CodeFirst One To Many - Fluent API

I have the following two classes:
public class Person
{
public int Id { get; set; }
public string FullName { get; set; }
}
public class Trip
{
public int Id { get; set; }
public string Name { get; set; }
public virtual IEnumerable<Person> Persons { get; set; }
}
As you can see, a Trip can have 1 or more Persons...
I tried to use the EntityConfiguration to build the database properly but I cannot manage to make it work... I am quite confused on its usage:
public class TripConfiguration : EntityTypeConfiguration<Trip>
{
internal TripConfiguration()
{
// ???
}
}
What do I need to write to have the application to behave properly:
I need at least one person.
I might have more that one person
A person cannot be in the SAME trip twice
A person can be in more than one trip
Try this:
this.HasRequired(x => x.Person)
.WithMany(x => x.Trips)
.HasForeignKey(x => x.PersonId);
Your classes:
public class Person
{
public int Id { get; set; }
public string FullName { get; set; }
public virtual ICollection<Trip> Trips { get; set;}
}
public class Trip
{
public int Id { get; set; }
public string Name { get; set; }
public int PersonId { get; set; }
public virtual Person Person { get; set; }
}
And as far that I know, EF doesn't support unique FK (or correct me if I'm wrong..). So you have to check it yourself.
This is not a One-To-Many relationship, this is a Many-To-Many relationship, you need to have collections on both sides of the relationship. EF will create the joiner table on your behalf. Since today you cannot configure a person being in a trip only once you will need to create a unique constraint in your joiner table once is created to assure this happens since EF does not yet support Unique Key constraints through configuration.
public class Person
{
public int Id { get; set; }
public string FullName { get; set; }
public virtual ICollection<Trip> Trips { get; set; }
}
public class Trip
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Person> Persons { get; set; }
}
then
class PersonConfiguration : EntityTypeConfiguration<Person>
{
public PersonConfiguration()
{
this.HasMany(t => t.Trips).WithMany(t => t.Persons);
}
}

Entity Framework 4.3.1 how to create associations

my code like below
public class User
{
public int ID { get; set; }
public int BillingAddressID { get; set; }
public Address BillingAddress { get; set; }
public IList<Shipment> Shipments { get; set; }
}
public class Address
{
public int ID { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string ZipCode { get; set; }
}
public class Shipment
{
public int ID { get; set; }
public string State { get; set; }
public int DeliveryAddressID { get; set; }
public Address DeliveryAddress { get; set; }
public User ShipUser { get; set; }
//[ForeignKey("ShipUser")]
public int ShipUserID { get; set; }
//public int UserId { get; set; }
}
public class TestContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<Shipment> Shipments { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Shipment>().HasRequired(u => u.ShipUser)
.WithMany(d => d.Shipments)
.HasForeignKey(c => c.ShipUserID)
.WillCascadeOnDelete(false);
}
}
if i remove the override method,i will get an error "SqlException: Introducing FOREIGN KEY constraint 'FK_Shipments_Users_ShipUserID' on table 'Shipments' 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. See previous errors."
if i remove ShipUserID in Shipment Class,it will work ok,when i see the table that is created by ef,i found a column named Shipment_UserID in table Shipment.I don`t know why.
if rename the class indenty key to UserID,it also work ok.
I try it anyway,but I don`t know the reason, I need some books about EF associations.
If you don't have mapping specified without cascadeDelete=false for one relationship it will create multiple cascade paths if you have tow relationships to user from Shipment.
By convention you can use public
Public User ShipUser { get; set; }
public int ShipUserID { get; set; }
it will use ShipUserID as foreign key by convention.
If you remove ShipUserID Ef need to create his own foreign key to keep the relationship . that is your ' Shipment_UserID'
rename the class indenty key to UserID I don't understand what you meant.
Here is a good tutorial to start with

EF code first error "The specified index already exists. [ IX_Id ]" for object tree

Using EF code first 4.3 I'm trying to model an object tree with a required-required relationships and a required-optional relationships.
Here is a simple representation of those classes
public class Top
{
public int Id { get; set; }
public virtual Middle Middle { get; set; }
}
public class Middle
{
public int Id { get; set; }
public virtual Child Child { get; set; }
}
public class Child
{
public int Id { get; set; }
}
Here is the OnModelCreating code
modelBuilder.Entity<Top>().HasRequired(t => t.Middle).WithRequiredPrincipal().WillCascadeOnDelete();
modelBuilder.Entity<Middle>().HasRequired(t => t.Child).WithOptional().WillCascadeOnDelete();
This produces the error "The specified index already exists. [ IX_Id ]" on SQLCE
After checking the db schema, both model binder fluent API configuration lines create an index IX_Id on the table Middles.
Does anyone know how to work around that problem?
Is there a way to set the index name?
Thank you!
Pascal
use this code ;
public class Top
{
public int Id { get; set; }
public int MiddleId { get; set; }
[ForeignKey("MiddleId")]
public virtual Middle Middle { get; set; }
}
public class Middle
{
public int Id { get; set; }
public int ChildId { get; set; }
[ForeignKey("ChildId")]
public virtual Child Child { get; set; }
}
public class Child
{
public int Id { get; set; }
}

How do I code an optional one-to-one relationship in EF 4.1 code first with lazy loading and the same primary key on both tables?

I'm working with an application and data structure built upon ASP/ADO.NET and I'm converting part of it to ASP.NET MVC. In the data structure, there exists a "optional one-to-one" relationship, where both tables use the same primary key, and name. Basically this table can be considered an "optional extension" of the primary table. Here are samples of the model:
public class ZoneMedia
{
public int ZoneMediaID { get; set; }
public string MediaName { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public virtual ZoneMediaText MediaText { get; set; }
}
public class ZoneMediaText
{
public int ZoneMediaID { get; set; }
public string Text { get; set; }
public int Color { get; set; }
}
Obviously, EF 4.1 code first has an issue mapping this automatically. So I realize I must specify the mapping explicitly. I tried this:
modelBuilder.Entity<ZoneMedia>()
.HasOptional(zm => zm.ZoneMediaText);
modelBuilder.Entity<ZoneMediaText>()
.HasRequired(zmt => zmt.ZoneMedia)
.WithRequiredDependent(zm => zm.ZoneMediaText)
.Map(m => m.MapKey("ZoneMediaID"));
But it is still giving me an exception about the name of the primary key.
Schema specified is not valid. Errors:
(199,6) : error 0019: Each property name in a type must be unique. Property name 'ZoneMediaID' was already defined.
I'm a little stumped. I need to adapt to this non-conventional structure I realize in EF 4.1 it would be much easier to just add a unique PK to the optional relation and hold the foreign key relationship in the primary table, but I can't change the database layout. Any advice would be appreciated.
I hope i understood well.
This works for me:
public class ZoneMedia
{
public int ZoneMediaID { get; set; }
public string MediaName { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public virtual ZoneMediaText MediaText { get; set; }
}
public class ZoneMediaText
{
public int ZoneMediaID { get; set; }
public string Text { get; set; }
public int Color { get; set; }
public virtual ZoneMedia ZoneMedia { get; set; }
}
public class TestEFDbContext : DbContext
{
public DbSet<ZoneMedia> ZoneMedia { get; set; }
public DbSet<ZoneMediaText> ZoneMediaText { get; set; }
protected override void OnModelCreating (DbModelBuilder modelBuilder)
{
modelBuilder.Entity<ZoneMedia>()
.HasOptional(zm => zm.MediaText);
modelBuilder.Entity<ZoneMediaText>()
.HasKey(zmt => zmt.ZoneMediaID);
modelBuilder.Entity<ZoneMediaText>()
.HasRequired(zmt => zmt.ZoneMedia)
.WithRequiredDependent(zm => zm.MediaText);
base.OnModelCreating(modelBuilder);
}
}
class Program
{
static void Main (string[] args)
{
var dbcontext = new TestEFDbContext();
var medias = dbcontext.ZoneMedia.ToList();
}
}
This Correctly create a FK_ZoneMediaTexts_ZoneMedias_ZoneMediaID in ZomeMediaTexts table, and the Foreign Key is the Primary Key.
EDIT: maybe it's worth pointing out that I'm using EF 4.3.0