我的表格中包含smalldatetime NOT NULL
字段,默认值为getdate()
。在表中创建新记录时,我没有通过LINQ To SQL语法在代码中设置smalldatetime
字段,我只是让数据库设置默认值,即当前日期。如果我没有在代码中明确设置它,则会引发以下错误:
SqlDateTime溢出。必须在1/1/1753 12:00:00 AM和12/31/9999 11:59:59 PM之间。
如果我在数据库中设置默认值,为什么我必须在代码中设置它?在LINQ To SQL中,我注意到了带日期的时髦事物。
答案 0 :(得分:3)
您可以考虑将其IsDbGenerated
值设置为AutoSync
,而不是将字段设置为OnInsert
。 IsDbGenerated
将不允许您设置字段的值(可能是您想要的“创建日期”字段,但不是“最后修改”字段)。
但是,如果您正在使用ORM,我会要求您考虑是否在数据库和应用程序代码中都需要应用程序逻辑。在代码中实现默认值更有意义吗(通过Insert[Entity]
之类的partial methods)?
答案 1 :(得分:1)
您必须设置生成的属性,以便LINQ to SQL不会发送其默认值以进行创建。
该属性在实体上称为“自动生成的值”。
答案 2 :(得分:0)
LINQ To SQL不以某种方式观察数据库默认值,然后您可以随后更新该值。为了实现这一点,您需要在代码中设置默认值。
使用数据库默认值创建NOT NULL
的新对象时,C#将使用默认值,例如MinValue
表示数字和日期,空GUID(零)等。您可以查找这些条件并替换为您自己的默认值。
这是LINQ To SQL的一个已知设计问题。有关深入讨论,请参阅此链接:
http://www.codeproject.com/KB/linq/SettingDefaultValues.aspx
用于在应用程序中设置默认值的一些示例代码:
private void SetDefaults(object LinqObj)
{
// get the properties of the LINQ Object
PropertyInfo[] props = LinqObj.GetType().GetProperties();
// iterate through each property of the class
foreach (PropertyInfo prop in props)
{
// attempt to discover any metadata relating to underlying data columns
try
{
// get any column attributes created by the Linq designer
object[] customAttributes = prop.GetCustomAttributes
(typeof(System.Data.Linq.Mapping.ColumnAttribute), false);
// if the property has an attribute letting us know that
// the underlying column data cannot be null
if (((System.Data.Linq.Mapping.ColumnAttribute)
(customAttributes[0])).DbType.ToLower().IndexOf("not null") != -1)
{
// if the current property is null or Linq has set a date time
// to its default '01/01/0001 00:00:00'
if (prop.GetValue(LinqObj, null) == null || prop.GetValue(LinqObj,
null).ToString() == (new DateTime(1, 1, 1, 0, 0, 0)).ToString())
{
// set the default values here : could re-query the database,
// but would be expensive so just use defaults coded here
switch (prop.PropertyType.ToString())
{
// System.String / NVarchar
case "System.String":
prop.SetValue(LinqObj, String.Empty, null);
break;
case "System.Int32":
case "System.Int64":
case "System.Int16":
prop.SetValue(LinqObj, 0, null);
break;
case "System.DateTime":
prop.SetValue(LinqObj, DateTime.Now, null);
break;
}
}
}
}
catch
{
// could do something here ...
}
}
答案 3 :(得分:0)
要解决此问题,请确保您的LINQ To SQL模型知道您的smalldatetime
字段是由数据库自动生成的。
在LINQ To SQL图中选择表的字段,然后找到“属性”窗口。将自动生成值属性调整为 True 。这将确保字段不包含在LINQ To SQL生成的INSERT
语句中。
或者,您必须自己指定:
if (newCustomer.DateTimeCreated == null) {
newCustomer.DateTimeCreated = DateTime.Now; // or UtcNow
}