插入guid作为主键-最佳实践

时间:2018-09-17 10:36:12

标签: c# entity-framework

使用GUId作为主键。这是在插入过程中实现它的正确方法吗?

    var item = new tbl_A(){
    Id = Guid.NewGuid().ToString("D")    
    };
  _context.tbl_A.Add(item);
  _context.SaveChanges();

2 个答案:

答案 0 :(得分:2)

如果您使用的是SQL Server,则UniqueIndentifier / GUID PK和实体框架的最佳做法是:

  1. 设置数据库以使用(newsequentialid())在PK列上分配默认值。这将自动生成更适合于群集索引的新ID。不要在代码中使用(newid())或依靠Guid.NewGuid()来生成Guid。这些玩弄索引。
  2. 使用DatabaseGeneratedOption.Identity设置EF主键,以通知EF这些键将由数据库处理。
  3. 利用导航属性来管理FK分配,而不是FK属性。原因是在创建数据库在其中处理PK的父子层次结构时,直到SaveChanges和子级的父级不应具有可空值的FK时,您才知道父级ID。

例如,给定具有OrderLines的Order,OrderLine表将具有一个称为OrderId的FK并返回到Order。您不能:

var order = new Order 
{
  OrderNumber = orderVM.OrderNumber,
  // populate order details from view model...
}
context.Orders.Add(order);
foreach(orderLineVM in orderVM)
{
  var orderLine = new OrderLine
  {
     OrderId = order.OrderId // This will be 0 until after SaveChanges.
  }
  context.OrderLines.Add(orderLine);
}

相反,您希望Order包含OrderLines的映射集合,以便插入操作看起来更像:

var order = new Order 
{
  OrderNumber = orderVM.OrderNumber,
  // populate order details...
  OrderLines = orderVM.OrderLines.Select(ol => new OrderLine
  {
    // Populate order lines from view model.
  }).ToList(),
}
context.Orders.Add(order);

EF将在保存实体时处理FK关联。

在最坏的情况下,如果需要在客户端分配PK,请阅读newsequentialid()如何在SQL Server中生成Guid并实现帮助程序方法以创建匹配的Guid。请注意,如果您使用Oracle或其他支持UUID等的数据库,则应研究如何表示和索引它们,以使用补充索引的格式(Big End。Little Endian)。在这种情况下,您还可以使用DatabaseGeneratedOption.None来确保EF / dev知道PK是由代码分配的。

答案 1 :(得分:0)

您需要在实体内部使用一些属性。

public class Item : Entity{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.None)]
    public string Id{get;set;}
}