C# 使用Sql Server uniqueidentifier/更新日期列和Linq to Sql-最佳方法

C# 使用Sql Server uniqueidentifier/更新日期列和Linq to Sql-最佳方法,c#,sql-server,linq-to-sql,datetime,uniqueidentifier,C#,Sql Server,Linq To Sql,Datetime,Uniqueidentifier,无论正确与否,我使用唯一标识符作为sqlserver数据库中表的主键。我已经使用linq to sql(c#)生成了一个模型,但是在标识列的情况下,linq to sql在插入guid/uniqueidentifier的新记录时为00000000-0000-0000-0000-00000000的默认值生成一个唯一键 我知道我可以在代码中设置guid:在linq to sql模型或其他地方,或者在创建sql server表时有默认值(尽管这被代码中生成的值覆盖)。但是在哪里生成这个键是最好的,注意

无论正确与否,我使用唯一标识符作为sqlserver数据库中表的主键。我已经使用linq to sql(c#)生成了一个模型,但是在
标识
列的情况下,linq to sql在插入
guid
/
uniqueidentifier
的新记录时为
00000000-0000-0000-0000-00000000
的默认值生成一个唯一键

我知道我可以在代码中设置guid:在linq to sql模型或其他地方,或者在创建sql server表时有默认值(尽管这被代码中生成的值覆盖)。但是在哪里生成这个键是最好的,注意我的表总是会随着我的解决方案的发展而改变,因此当我的Linq到Sql模型改变时,我将重新生成它


相同的解决方案是否适用于保存当前
datetime
(插入)的列,该列将随每次更新而更新?

您可以做两件事:

  • 或者在C#客户端代码中生成GUID并使用该值
  • 在SQL Server中的GUID列上创建默认约束,该列的默认值为
    newid()
    ,SQL Server将确保始终添加默认值,除非您自己指定值
至于自更新日期/时间列,这里可能需要使用客户端逻辑,或者如果要在SQL Server上执行此操作,则必须编写触发器。这实际上是每次更新行时更新特定列的唯一方法-没有“自动更新”约束或类似的约束(默认约束仅适用于插入,而不适用于更新)

类似的方法可能会奏效:

CREATE TRIGGER TRG_UpdateDateTimestamp
ON (your table name)
AFTER UPDATE 
AS
    IF NOT UPDATE(DateTimeStamp)
    BEGIN
       UPDATE (yourtablename) 
       SET DateTimeStamp = GETDATE()
       WHERE EXISTS (SELECT * FROM inserted AS i 
                     WHERE i.OID = (yourtable).OID)
   END

Marc

正如您在自己的帖子中所指出的,您可以使用可扩展性方法。在文章中,您可以查看在datacontext中创建的用于插入和更新每个表的分部方法。一个名为“test”的表和一个“changeDate”列的示例:


谢谢,我已经试过了,看起来还可以。
我有另一种方法,我想我应该用于guid:sqlserver默认值为newid(),然后在linqtosql中将auto-generated-value属性设置为true。这必须在模型的每一代上进行,但这相当简单。

谢谢Marc,默认linq to sql生成代码的问题在于它生成了0s guid,因此sqlserver创建的默认值被覆盖(我相信我已经找到了解决方案-我自己添加了一个答案)。虽然触发器看起来很有用,但我会尝试一下,尽管我觉得我需要一个更通用的解决方案,以避免为每个表编写此代码。也许我应该有一个通用的Updates表,cols为tname、id和datetime,在每个表上都有一个触发器来运行一个通用存储过程,以便在该表中插入一条新记录?这是可行的吗?由于某些原因,我的答案没有出现,答案可以在这里找到:谢谢Stephan,我认为这可能是我首选的方法,UpdateTest(…)看起来不错,但是在OnCreated上使用InsertTest的一个问题是,在对象生命周期中,与其他相关对象相关的地方可能会发生。我是否可以使用默认0创建指向其他对象的链接,但我尚未生成guid?如果相关对象作为实体集附加到父对象,则相关对象的外键将在插入后更新。但是,我发现在OnCreate方法中设置guid没有任何错误。我使用Insert方法是因为我需要设置一个唯一的连续编号(例如发票编号),该编号取自数据库中的编号池。对于唯一的键,我使用标识列。谢谢,我已经尝试过了,它似乎工作正常。我使用了最初的OnCreated()方法,但现在改为这种方法。这种方法不适用于guid,因为对于集合,在调用insert方法之前添加了重复的0s键,因此会引发异常。我有另一种方法,我想我应该用于guid:sqlserver默认值为newid(),然后在linqtosql中将auto-generated-value属性设置为true。这必须在每一代模型上完成,但这相当简单。
partial void InsertTest(Test instance)
{
    instance.idCol = System.Guid.NewGuid();
    this.ExecuteDynamicInsert(instance);
}

partial void UpdateTest(Test instance)
{
    instance.changeDate = DateTime.Now;
    this.ExecuteDynamicUpdate(instance);
}