不将date属性设置为object会导致错误

时间:2010-11-29 16:25:28

标签: c# linq-to-sql sql-server-2008

我的表格中包含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中,我注意到了带日期的时髦事物。

4 个答案:

答案 0 :(得分:3)

您可以考虑将其IsDbGenerated值设置为AutoSync,而不是将字段设置为OnInsertIsDbGenerated将不允许您设置字段的值(可能是您想要的“创建日期”字段,但不是“最后修改”字段)。

但是,如果您正在使用ORM,我会要求您考虑是否在数据库和应用程序代码中都需要应用程序逻辑。在代码中实现默认值更有意义吗(通过Insert[Entity]之类的partial methods)?

答案 1 :(得分:1)

您必须设置生成的属性,以便LINQ to SQL不会发送其默认值以进行创建。

该属性在实体上称为“自动生成的值”。

alt text

答案 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语句中。

alt text

或者,您必须自己指定:

if (newCustomer.DateTimeCreated == null) {
       newCustomer.DateTimeCreated = DateTime.Now; // or UtcNow 
 }