EF Code-first,插入时如何将主键插入另一个字段?
EF Code-first, how to insert primary key to another field when inserting?
这是我要插入数据库的实体:
public sampleEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PrimaryKey { get; set; }
[Required]
public string Ticket { get; set; }
}
Ticket
的格式类似于
string.Format("{0:yyyyMMdd}-{1}", DateTime.Now, PrimaryKey);
因此,当我将此实体添加到上下文时,primaryKey
始终为 0,因此 Ticket
值始终为“20170315-0”
目前我的解决方案是
// first add row and save
SampleEntity sample = new SampleEntity {
Ticket=DateTime.Now.ToString("yyyyMMdd")
};
context.Samples.Add(sample);
context.SaveChanges();
// then find it out and update
var latest = context.Samples.OrderByDecending(p => p.PrimaryKey).First();
latest.Ticket += sample.PrimaryKey.ToString();
context.SaveChanges();
如何在SaveChanges()
没有更新的情况下根据primaryKey
值设置Ticket
值?
您有 DatabaseGeneratedOption.Identity
主键选项。
这意味着只有 SQL服务器知道那个ID,并且那个知识在实际只有的那一刻具体化INSERT
进入数据库(因为数据库中的相关列是某种 IDENTITY
列)。
例如,考虑两个同时向数据库中插入新记录的应用程序 - 它们将接收不同的密钥,但您无法确定哪个应用程序接收哪个密钥。
Entity Framework 将为 SaveChanges
生成两个请求 - 第一个是 INSERT
,另一个是 SELECT
以接收生成的密钥。
只有在那之后,您的代码才会知道实际密钥并能够将其用于您的机票计算 - 所以基本上您无法避免使用 EF 的另一个 UPDATE
。
不过,您可以做的是更改由您的代码而不是数据库控制的内容的主键类型 - 例如,随机 GUID;在这种情况下,您将知道 ID before insert 并且可以以任何您想要的方式使用它。
但是对主键使用 GUID 会导致其他并发症,这在大多数情况下是不值得的,比如非顺序插入会导致经常重建索引,仍然有一定的键冲突可能性,更多 space 保留专栏等
另一种选择是在应用程序中为票证列设置 计算 列或类似逻辑,因此您将有单独的日期列和单独的 ID 列,但对于票证,您要么始终在需要时应用 concat 逻辑,创建仅 return 值的计算列(因此对于数据库和 EF 是只读的)。
这是我要插入数据库的实体:
public sampleEntity
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PrimaryKey { get; set; }
[Required]
public string Ticket { get; set; }
}
Ticket
的格式类似于
string.Format("{0:yyyyMMdd}-{1}", DateTime.Now, PrimaryKey);
因此,当我将此实体添加到上下文时,primaryKey
始终为 0,因此 Ticket
值始终为“20170315-0”
目前我的解决方案是
// first add row and save
SampleEntity sample = new SampleEntity {
Ticket=DateTime.Now.ToString("yyyyMMdd")
};
context.Samples.Add(sample);
context.SaveChanges();
// then find it out and update
var latest = context.Samples.OrderByDecending(p => p.PrimaryKey).First();
latest.Ticket += sample.PrimaryKey.ToString();
context.SaveChanges();
如何在SaveChanges()
没有更新的情况下根据primaryKey
值设置Ticket
值?
您有 DatabaseGeneratedOption.Identity
主键选项。
这意味着只有 SQL服务器知道那个ID,并且那个知识在实际只有的那一刻具体化INSERT
进入数据库(因为数据库中的相关列是某种 IDENTITY
列)。
例如,考虑两个同时向数据库中插入新记录的应用程序 - 它们将接收不同的密钥,但您无法确定哪个应用程序接收哪个密钥。
Entity Framework 将为 SaveChanges
生成两个请求 - 第一个是 INSERT
,另一个是 SELECT
以接收生成的密钥。
只有在那之后,您的代码才会知道实际密钥并能够将其用于您的机票计算 - 所以基本上您无法避免使用 EF 的另一个 UPDATE
。
不过,您可以做的是更改由您的代码而不是数据库控制的内容的主键类型 - 例如,随机 GUID;在这种情况下,您将知道 ID before insert 并且可以以任何您想要的方式使用它。
但是对主键使用 GUID 会导致其他并发症,这在大多数情况下是不值得的,比如非顺序插入会导致经常重建索引,仍然有一定的键冲突可能性,更多 space 保留专栏等
另一种选择是在应用程序中为票证列设置 计算 列或类似逻辑,因此您将有单独的日期列和单独的 ID 列,但对于票证,您要么始终在需要时应用 concat 逻辑,创建仅 return 值的计算列(因此对于数据库和 EF 是只读的)。