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完成的,并且在某些情况下,默认值比硬编码值稍微复杂一些(例如,根据另一个字段创建默认值)所以我想而是避免重复那个逻辑.
不幸的是,Linq to SQL不支持数据库默认值.请看这里的第一个问题:
他们建议的是,您为相关实体提供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
总而言之,解决方案真的很糟糕.祝好运!