У меня есть не допускающий NULL-значения столбец базы данных, которому установили значение по умолчанию. При вставке строки иногда значение указано для столбца, иногда каждый не. Это хорошо работает в 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]
Следующие два оператора будут работать:
INSERT INTO Table1 (col1, col2) VALUES ('test value', '')
INSERT INTO Table1 (col2) VALUES ('')
Во втором операторе значение по умолчанию используется для col1.
Проблема, которую я имею, при использовании LINQ-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();
Если свойство Auto Generated Value col1 является Ложью, первая строка создается, как желаемый, но вторые сбои строки с пустой ошибкой на col1. Если Автоматическое Сгенерированное Значение Правда, обе строки создаются со значением по умолчанию из базы данных. Я попробовал различные комбинации Автоматического Сгенерированного Значения, Auto-Sync и Nullable, но ничто я попробовал, дают поведение, которое я хочу.
L2S не опускает столбец от оператора вставки, когда никакое значение не указано. Вместо этого это делает что-то вроде этого:
INSERT INTO Table1 (col1, col2) VALUES (null, '')
... который, конечно, вызывает пустую ошибку на col1.
Там некоторый путь состоит в том, чтобы заставить L2S опускать столбец от оператора вставки, если никакое значение не дано? Или там некоторый другой путь состоит в том, чтобы получить поведение, которое я хочу? Мне нужно значение по умолчанию на уровне базы данных, потому что не все вставки строки сделаны через L2S, и в некоторых случаях значение по умолчанию немного более сложно, чем твердое кодированное значение (например, создание значения по умолчанию на основе другого поля), таким образом, я постарался бы не копировать ту логику.
К сожалению, Linq to SQL не поддерживает значения по умолчанию для базы данных. См. Первый вопрос здесь:
Они предлагают что вы предоставляете реализацию метода Insert для рассматриваемой сущности. Подпись
partial void Insert[EntityName](Entity instance)
Итак, если у вас есть сущность с именем Person, которой вы хотели бы иметь значение по умолчанию «Home» для поля PhoneNumberDesc, вы могли бы реализовать это следующим образом:
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());
}
Возможно, вам удастся избежать неприятностей. реализация события OnCreated, которое вызывается каждым конструктором для каждой сущности. Эта статья немного объясняет, как точки расширения в Linq To SQL: http://msdn.microsoft.com/en-us/library/bb882671.aspx
В общем, решение действительно отстой. Удачи!
Я не уверен насчет LINQ, но в SQL, если вы хотите использовать значение по умолчанию, сделайте это в любом случае:
INSERT INTO Table1 (col2) VALUES ('X')
или
INSERT INTO Table1 (col1, col2) VALUES (DEFAULT, 'X')