Imoum
Imoum

Reputation: 745

Foreign-Key References to the Same Entity

I have the below model:

class Client
{        
    [Key]
    public int Id { get; set; }
    public string Nom { get; set; }
    public string Prenom { get; set; }         
    public Nullable<DateTime> date_naissance { get; set; }
    public Sex? Sexe { get; set; }
    public Client Parent { get; set; }
}

I used code first to generate my table. When I tried to save the records using the code below, I wasn't able to determine how to populate the Parent field. A Client can be a parent of other Clients.

Client client = new Client();

client.Id = int.Parse(item.ID);
client.Nom = item.Nom;
client.Prenom = item.Prenom;
client.date_naissance = DateTime.Parse(item.DateNaissance);
client.Sexe = (Sex)Enum.Parse(typeof(Sex), item.Sexe);

int parent;
bool par = int.TryParse(item.Parent, out parent);

// this does not work:                       
if (par)
    client.Parent.Id = parent;

db.clients.Add(client);
db.SaveChanges();

Upvotes: 0

Views: 71

Answers (4)

Brett Wolfington
Brett Wolfington

Reputation: 6627

If the parent Client instance is not already created, you will need to create a new one. You can always create a new Client instance and assign it the parent's Id, but the instance assigned will lack all of the other information about the parent. An example of this is below.

client.Parent = new Client() { Id = parentId };

Ideally, you will look up the parent from the context and assign it to the client:

var parent = context.Clients.Find(parentId);
if (parent != null)
{
    client.Parent = parent;
}
else
{
    // Handle an invalid ID
}

Additionally, I would suggest changing the Parent property to a virtual property:

public virtual Client Parent { get; set; }

This will allow you to take advantage of two useful features of the Entity Framework: lazy loading and automatic change tracking. Entities or collections of entities referenced by navigation properties specified with the virtual keyword will only be loaded the first time they are used. With the virtual keyword, accessing the Parent property the first time will load the Parent entity for that Client and return it. Without the virtual keyword, the Parent property will return null unless you explicitly load and assign a value to it.

Upvotes: 2

stann1
stann1

Reputation: 635

Try making the navigation properties (i.e. Parent) virtual and don't forget to initialize them. So first you have to change your class property to:

public virtual Client Parent { get; set; }

and then in the code:

client.Parent = new Parent();
client.Parent.Id = parentId;

Upvotes: 0

3Ducker
3Ducker

Reputation: 346

You may not want to pass the whole Client structure as the parent, you may pass only the integer ID to refer to the parent.

Upvotes: 0

Chaka
Chaka

Reputation: 387

you must create an instance of the parent. or you can't set it.

class Client
{                
    public int Id { get; set; }

    public Client Parent { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="Client"/> class.
    /// 
    /// WITH PARENT
    /// </summary>
    /// <param name="id">The identifier.</param>
    /// <param name="parent">The parent.</param>
    public Client(int id, Client parent)
    {
        this.Id = id;
        this.Parent = parent;                    
    }

    /// <summary>
    /// Initializes a new instance of the <see cref="Client"/> class.
    /// 
    /// WITHOUT PARENT
    /// </summary>
    /// <param name="id">The identifier.</param>
    public Client(int id)
    {
        this.Id = id;
    }
}

public static void Main(string[] args)
{
        Client client = new Client(1);

        Client clientWithParent = new Client(2, client);

        Console.Write("parent id :" + clientWithParent.Parent.Id);
}

Upvotes: -1

Related Questions