Click here to Skip to main content
15,890,609 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am pretty sure, the answer to this question should be easy, but I cannot find the answer after hours of googling...

- I do use Entity Framework and have two kind of objects, lets say one Street and several houses. The relationship is clear. One Street contains one or more houses.
This objects in EF looks like the following:

ctx.street.houses

etc.
If I use
ctx.street.houses.Add(newhouse)

I end up with a new house object in a database. Fine.

But how can I add an already given "house" object into the street? I always get a new house object and cannot get it to work to use my already created objects.

I found the Attach() function instead of the Add() function for the collection, but the
ctx.street.houses.Attach()

Function doesn`t exist in my environment, so this isn`t a solution at all.

Any one who can clear this up?


[EDIT]
C#
public partial class DBEntity: DbContext
    {
        public DBEntity()
            : base("name=DBEntity1")
        {
        }
    
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    
        public virtual DbSet<client> Clients { get; set; }
        public virtual DbSet<contactperson> ContactPersons { get; set;}
    }



The Clients class:

C#
public partial class Client
   {
       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
       public Client()
       {
           this.ContactPersons = new HashSet<contactperson>();
       }

       public int Id { get; set; }
       public string Company { get; set; }
       public System.DateTime Date_Creation { get; set; }
       public bool Active { get; set; }

       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
       public virtual ICollection<contactperson> ContactPersons { get; set; }
       [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]

   }


and the ContactPerson class:

C#
public partial class ContactPerson
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public ContactPerson()
        {
            
        }
 
        public int Id { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public System.DateTime Date_Creation { get; set; }
        public bool Active { get; set; }
        public string EMail { get; set; }
        public string Phone_Office { get; set; }
        public string Phone_Mobile { get; set; }
 
        public virtual Client Client { get; set; }
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
       
    }

[/EDIT by Maciej Los (content moved from comment/answer]
Posted
Updated 10-Mar-15 2:19am
v2
Comments
Maciej Los 10-Mar-15 6:13am    
Please, provide information about your entity model class(es).

Assuming you have a "Street" navigation property on the House entity, you should be able to do something like this:
C#
existingHouse.Street = existingStreet;
 
Share this answer
 
Comments
je-wo 10-Mar-15 4:38am    
but where is the difference between

<pre>existingHouse.Street = existingStreet;</pre>

and

<pre>existingStreet.Houses = existingHouse;</pre>


how do I know which direction is the right one? It should work in both directions, shoudln`t it?
Member 11428137 10-Mar-15 4:50am    
Yes it should be able to work both ways, but since existingStreet.Houses is a collection you have to .Add your house to it.
As I understood from your question, when you .Add an existing house, it is creating a duplicate house in the database.
Without seeing more of your code, I'm not sure why it would be doing that.
je-wo 10-Mar-15 6:22am    
Tried it with

existingHouse.Street = existingStreet;

But the result is the same, I get another "new" existingStreet object created in the database with a new id. Everything else is an exact copy of the "original" existing street.
First of all, please, read my comment to the question.

The relationship between house and street is preety clear: 1 street can contain several houses. This relationship is called one to many.
As per my understanding, the model of hierarchy looks like:
Street
+----Houses
     +----House
     +----House
     +----House


So, i do not understand what you mean by saying "attach already given house into the street", because each house belongs to the collection of houses which belong to the single street.
 
Share this answer
 
Comments
je-wo 10-Mar-15 6:51am    
Yes, that is exactly the relationship. But I do have the case that a Street object gets created with no houses attached to it. And one or more house objects get created without knowledge of a street.

Now, after both types of objects are available, I`d like to connect them. So, I`d like to add a house to a street, but both objects already exist in the database.

The code looks like this:

House h1 = new House();
ctx.Houses.Add(h1);

Street s1 = new Street();
ctx.Streets.Add(s1);
ctx.SaveChanges();

so far, so good. Now, I`d like to do the connection between the extisting House and Street objects:

// adds h1 to the strees with the ID no. 5:
ctx.Streets.Where (x=>x.ID == 5).First().Houses.Add(h1);

But with this code, the EF thinks,I`d like to create a new house object in the DB and so it does. Why doesn`t it connect the already created and existing h1 house to the street with the id no. 5? And how to change this behaviour...or is my thinking wrong and I need to change my approach?

Problem is, that all the houses gets created at a time I do know nothing about the street they will get added to, later on. So, I need to have the possiblity to add houses to the collection of houses in a street at a later time.

Hope this was explained in a way that it is understandable...
Maciej Los 10-Mar-15 6:59am    
I do not understand how this could be possible: ctx.Houses.Add(h1); if the collection of houses belongs to the Street? Please, provide more information about your enitity model (improve question and add a code).
As per my understanding, you should add house this way:
s1.Houses.Add(h1);
or
ctx.Streets[0].Houses.Add(h1);
je-wo 10-Mar-15 7:26am    
I do have one table called "House" and one table that is called "Street".
"Street" contains street information and "House" contains house information.
"Street" does have an association to "House" by 0...many relationship. So, each Street object contains a list of house objects...even if it is empty.

We now create one or more House object(s) and store it in the DB. Afterwards
we create one or more Street object(s) and store it in the DB
For example:

House h1 = new House();
ctx.Houses.Add(h1);

House h2 = new House();
ctx.Houses.Add(h2);

Street s1 = new Street();
ctx.Streets.Add(s1);
ctx.SaveChanges();

Then...a while later we need to tell the street, which already created house objects (stored in the DB table "House") belongs to it. Therefore we need to connect already created House objects to one Street Object.

My idea was, to Add() all House objects to the List of houses in the Street.
So, I called:

ctx.Streets.Where (x=>x.ID == 5).First().Houses.Add(h1);
ctx.Streets.Where (x=>x.ID == 5).First().Houses.Add(h2);
etc.

But instead of the expected connection, it created two new house objects in the "House" table.

The two "old" house objects are still there but are not connected to any other object. Two "new" house objects are also there AND connected to the Street.
But I do not want objects to get copied, I want the original house objects to be connected to the Street...

Thank you very much in advance...
Maciej Los 10-Mar-15 7:33am    
So, you need to create "connection" (relationship) between street and houses...
You still does not show me entity model class.
je-wo 10-Mar-15 8:17am    
There is the Entity Model class:
There are Clients (aka the Streets) and ContactPersons (aka the houses)

--- Maciej Los --
Content has been moved to the question

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900