Entity Framework one to many relation code first
You need to map both properties participating in the relationship. You need to add ClientID
column to Orders table.
class ClientMapping
{
ClientMapping()
{
this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID");
this.Property(e => e.Name).HasColumnName("Name");
this.HasMany(e => e.Orders).WithRequired(o => o.Client)
.Map(p => p.MapKey("ClientID")).WillCascadeOnDelete();
this.ToTable("Clients");
}
}
class OrderMapping
{
OrderMapping()
{
this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID");
this.Property(e => e.Details).HasColumnName("Details");
this.ToTable("Orders");
}
}
Configuring the relationship from one entity is sufficient.
rideronthestorm
Updated on June 04, 2022Comments
-
rideronthestorm almost 2 years
I am having my first steps in EF 4.1. Because I was using NHibenate, the code first approach seems to me as the best one. I have problem with good mapping of one-to-many (or many-to-one) realtionship. Let's say I have 2 entities:
class ClientModel { int ClientID; string Name; virtual IList<OrderModel> Orders; } class OrderModel { int OrderID; string Details; virtual ClienModel Client; }
When I leave it like that, there is an error while generating database - keys in tables are missing. I figured out I can fix it by changing names of the keys to ID (but it's not OK with my naming convention) or by adding [Key] annotation. Even if I add this annotation, still the names of tables are wrong - just like classes names but with 's'. So I tried to use fluent API - I made mappings. But if I set mappings just like here:
class ClientMapping { ClientMapping() { this.HasKey(e => e.ClientID).Property(e => e.ID).HasColumnName("ClientID"); this.Property(e => e.Name).HasColumnName("Name"); this.HasMany(e => e.Orders).WithOptional().Map(p => p.MapKey("OrderID")).WillCascadeOnDelete(); this.ToTable("Clients"); } } class OrderMapping { OrderMapping() { this.HasKey(e => e.OrderID).Property(e => e.OrderID).HasColumnName("OrderID"); this.Property(e => e.Details).HasColumnName("Details"); this.HasRequired(e => e.Client).WithMany().Map(p=>p.MapKey("Client")).WillCascadeOnDelete(false); this.ToTable("Orders"); } }
the relation betweene tables in database is doubled. What is the proper way to do one-to-many relationship using code-first approach? Am I thinking in a good direction or is it a wrong approach?
EDIT
OK, I have done it in the way @Eranga showed, but there is still a problem. When I'm getting Client from database, its Orders property is null (but in database it has some Orders with Order.ClientID == Client.ClientID).
-
Eranga over 12 yearsI tested the configuration given in my answer and it works fine. Make sure
Orders
is a property not a field. -
Jo Smo over 9 yearsTry
virtual List<OrderModel> Orders;
instead ofvirtual IList<OrderModel> Orders;
-
-
rideronthestorm over 12 years"You need to map both properties participating in the relationship. You need to add ClientID column to Orders table." What do you exactly mean by that?
-
Eranga over 12 years@rideronthestorm
Orders
property inClientModel
andClient
property inOrderModel
as the two participants of the relationship. -
rideronthestorm over 12 yearsI still don't understand it. Wasn't I mapping both of them? Maybe you could post full code for it? And why do I need ClientID in Orders (OrderModel?)?
-
Eranga over 12 years@rideronthestorm I posted the full code for mapping. The way you mapped will be interpreted by EF as two different relationships. Since an
Order
requires aClient
you need to added the foreign key columnClientID
toOrder
table -
rideronthestorm over 12 yearsIsn't ClienModel Client; enough as a foreign key?
-
rideronthestorm over 12 yearsAmd ypu are saying that I should put int ClientID instead of ClientModel Client? Why there is no Client or ClientID mapping?
-
rideronthestorm over 12 yearsAnd the other question is what is the difference if I set hasMany in client or withMany in order? These are 2 different ways to describe the same relation?
-
rideronthestorm over 12 yearsI did it like you said - so model has no changes, but mappnigs are like the ones you've posted. The database was generated without errors, but there is something wrong with it, because when I try to generate diagram for it in SQl Management Studio, I get the error "The table '<table_name>' no longer exists in the database" for each of my generated tables. However, they are accessible, I can see their columns, modify them, etc.
-
Eranga over 12 years@rideronthestorm You do not ned to add
ClientID
property toOrderModel
. EF will create a columnClientID
inOrders
table when you map the entities as I have shown.HasMany
is used when you map from the many side.WithMany
is used when you map form one side of the relationship to the many side. -
rideronthestorm over 12 years"HasMany is used when you map from the many side. WithMany is used when you map form one side of the relationship to the many side." - yes, I know that, but what is the difference in effect? In my example could I use withMany in Client instead of hasMany in order and effect (objects generated) would be the same?