对同一实体的外键引用

Foreign-Key References to the Same Entity

我有以下型号:

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; }
}

我首先使用代码生成我的 table。当我尝试使用下面的代码保存记录时,我无法确定如何填充 Parent 字段。 Client 可以是其他 Client 的父级。

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();

如果尚未创建父 Client 实例,您将需要创建一个新实例。您始终可以创建一个新的 Client 实例并为其分配父级的 ID,但分配的实例将缺少有关父级的所有其他信息。下面是一个例子。

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

理想情况下,您将从上下文中查找父级并将其分配给客户端:

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

此外,我建议将 Parent 属性 更改为虚拟 属性:

public virtual Client Parent { get; set; }

这将使您能够利用 Entity Framework 的两个有用功能:延迟加载和自动更改跟踪。由 virtual 关键字指定的导航属性引用的实体或实体集合只会在第一次使用时加载。使用 virtual 关键字,第一次访问 Parent 属性 将为 Client 和 return 加载 Parent 实体。如果没有 virtual 关键字,Parent 属性 将 return null 除非您显式加载并为其赋值。

您必须创建父项的实例。否则无法设置。

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);
}

您可能不想将整个 Client 结构作为父级传递,您可以只传递整数 ID 来引用父级。

尝试将导航属性(即父级)设为虚拟,并且不要忘记对其进行初始化。因此,首先您必须将 class 属性 更改为:

public virtual Client Parent { get; set; }

然后在代码中:

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