Ответ 1
Это ошибка в Linq-to-SQL. Он исправлен в .net 4.0.
См. Подключение № 381883: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381883
Я работал с простым классом сущностей с LINQ to SQL (SQL Server 2005 SP3 x64).
[Table( Name="TBL_REGISTRATION" )]
public sealed class Registration : IDataErrorInfo
{
[Column( Name = "TBL_REGISTRATION_PK", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
public Guid RegistrationID { get; private set; }
/* other properties ommited for brevity */
}
Здесь всего две интересные вещи:
Вот что выглядит таблица:
create table dbo.TBL_REGISTRATION
(
TBL_REGISTRATION_PK uniqueidentifier primary key clustered
rowguidcol
default newid(),
/* other columns ommited for brevity */
)
Когда я присоединяю этот объект к своей таблице и отправляю изменения в свой DataContext, стек LINQ возвращает исключение SqlException:
SqlException (0x80131904): Недопустимое имя столбца 'RegistrationID'
LINQ, похоже, игнорирует атрибут Column (Name = "TBL_REGISTRATION_PK" ) в моем свойстве RegistrationID. Я провел некоторое время с разными атрибутами атрибутов, пытаясь заставить его работать. В конце концов я остановился на частном свойстве TBL_REGISTRATION_PK, чтобы обернуть мое свойство RegistrationID, чтобы сделать LINQ счастливым.
[Table( Name="TBL_REGISTRATION" )]
public sealed class Registration : IDataErrorInfo
{
public Guid RegistrationID { get; private set; }
[Column( IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
private Guid TBL_REGISTRATION_PK { get { return RegistrationID; } set { RegistrationID = value; } }
/* other properties ommited for brevity */
}
Это работает.
Почему он не работал первым способом? Я делаю что-то неправильно здесь или это дефект LINQ?
Это ошибка в Linq-to-SQL. Он исправлен в .net 4.0.
См. Подключение № 381883: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381883
Ваша собственность нуждается 'private' удалена из 'private set;' Когда вы создаете свойства короткой руки в VS 2008 без реализации get/set, компилятор создает для вас частные переменные-члены (имя которых известно). Опция Storage в ColumnAttribute указывает, какой частный член использовать.
Linq to SQL не знает, как установить свойство, если вы помечаете setter private и публичный getter (не спрашивайте меня почему). Если вы хотите сделать свое свойство только для чтения, сделайте переменную частного члена, как вы это делали выше.
Вы можете очистить его, написав его следующим образом:
[Table( Name="TBL_REGISTRATION" )]
public sealed class Registration : IDataErrorInfo
{
public Guid RegistrationID { get { return _registrationID; } }
[Column( IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert)]
private Guid _registrationID;
}
Вы пытались использовать свойство Storage?
[Table( Name="TBL_REGISTRATION" )]
public sealed class Registration : IDataErrorInfo
{
[Column( Name="TBL_REGISTRATION_PK", Storage="_RegistrationID", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
public Guid RegistrationID { get { return _RegistrationID; } set { _RegistrationID = value; } }
private Guid _RegistrationID;
/* other properties ommited for brevity */
}
Используйте свойство "Хранение" с именем столбца:
[Column( Name="TBL_REGISTRATION_PK", Storage="TBL_REGISTRATION_PK", IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
public Guid RegistrationID { get { return _RegistrationID; } set { _RegistrationID = value; } }
Поскольку имя хранилища столбца TBL_REGISTRATION_PK.
Лучшим решением, которое я нашел для этой проблемы, является создание частного класса Guid в классе с таким же именем, что и первичный ключ в базе данных, и использовать его в качестве поля поддержки для свойства, которое соответствует Соглашения о присвоении имен в рамках Framework.
// Primary key to TBL_REGISTRATIONT
[Column( Name = "TBL_REGISTRATIONT_PK", IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
public Guid RegistrationID
{
get
{
return TBL_REGISTRATIONT_PK;
}
private set
{
TBL_REGISTRATIONT_PK = value;
}
}
[Column( IsPrimaryKey = true, IsDbGenerated = true, AutoSync = AutoSync.OnInsert )]
private Guid TBL_REGISTRATIONT_PK;