LINQ-to-SQL可以在插入时省略未指定的列,因此使用了数据库默认值吗?

Tod*_*pog 11 .net sql-server visual-studio-2008 linq-to-sql

我有一个不可为空的数据库列,它具有默认值集.插入行时,有时会为列指定值,有时则不会.当省略列时,这在TSQL中工作正常.例如,给出下表:

CREATE TABLE [dbo].[Table1](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [col1] [nvarchar](50) NOT NULL,
    [col2] [nvarchar](50) NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED ([id] ASC)
)
GO
ALTER TABLE [dbo].[Table1] 
    ADD CONSTRAINT [DF_Table1_col1] DEFAULT ('DB default') FOR [col1]
Run Code Online (Sandbox Code Playgroud)

以下两个陈述将起作用:

INSERT INTO Table1 (col1, col2) VALUES ('test value', '')  
INSERT INTO Table1 (col2) VALUES ('')     
Run Code Online (Sandbox Code Playgroud)

在第二个语句中,默认值用于col1.

我遇到的问题是使用LINQ-to-SQL(L2S)和这样的表.我想产生相同的行为,但我无法弄清楚如何让L2S做到这一点.我希望能够运行以下代码并让第一行获取我指定的值,第二行从数据库中获取默认值:

var context = new DataClasses1DataContext();
var row1 = new Table1 { col1 = "test value", col2 = "" };
context.Table1s.InsertOnSubmit(row1);
context.SubmitChanges();
var row2 = new Table1 { col2 = "" };
context.Table1s.InsertOnSubmit(row2);
context.SubmitChanges();
Run Code Online (Sandbox Code Playgroud)

如果col1的"自动生成的值"属性为False,则会根据需要创建第一行,但第二行会因col1上的空错误而失败.如果"自动生成的值"为"True",则使用数据库中的默认值创建这两行.我尝试了自动生成值,自动同步和Nullable的各种组合,但我尝试的没有给出我想要的行为.

当没有指定值时,L2S不会从insert语句中省略该列.相反,它做了这样的事情:

INSERT INTO Table1 (col1, col2) VALUES (null, '')
Run Code Online (Sandbox Code Playgroud)

...当然会在col1上导致null错误.

如果没有给出值,是否有某种方法可以让L2S省略insert语句中的列?或者是否有其他方式来获得我想要的行为?我需要数据库级别的默认值,因为并非所有行插入都是通过L2S完成的,并且在某些情况下,默认值比硬编码值稍微复杂一些(例如,根据另一个字段创建默认值)所以我想而是避免重复那个逻辑.

Jef*_*her 7

不幸的是,Linq to SQL不支持数据库默认值.请看这里的第一个问题:

http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/3ae5e457-099e-4d13-9a8b-df3ed4ba0bab/

他们建议的是,您为相关实体提供Insert方法的实现.签名是

partial void Insert[EntityName](Entity instance)
Run Code Online (Sandbox Code Playgroud)

因此,如果您有一个名为Person的实体,您希望PhoneNumberDesc字段的默认值为"Home",则可以通过以下方式实现:

    partial void InsertPerson(Person instance)
    {
        if (string.IsNullOrEmpty(instance.PhoneNumberDesc))
            instance.PhoneNumberDesc = "Home";

        var insertParams = new List<object>();
        var insertStatement = "insert into ...";

        // build the rest of the insert statement and fill in the parameter values here...

        this.ExecuteQuery(typeof(Person), insertStatement, insertParams.ToArray());
    }
Run Code Online (Sandbox Code Playgroud)

您可能能够实现OnCreated事件,该事件是使用每个实体的每个构造函数调用的.本文解释了Linq To SQL中可扩展性如何指出:http://msdn.microsoft.com/en-us/library/bb882671.aspx

总而言之,解决方案真的很糟糕.祝好运!