我正在使用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似乎忽略了我的RegistrationID属性上的Column(Name =“TBL_REGISTRATION_PK”)属性。我花了一些时间用不同的属性装饰试图让它工作。最后,我决定使用一个私有的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缺陷?
答案 0 :(得分:6)
这是Linq-to-SQL中的一个错误。它在.net 4.0中修复。
请参阅Connect#381883: https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=381883
答案 1 :(得分:2)
您的财产需要从'私人套餐'中删除'私人';在VS 2008中创建短手属性而不实现get / set时,编译器会为您创建私有成员变量(知道的名称)。 ColumnAttribute中的Storage选项指定要使用的私有成员。
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;
}
答案 2 :(得分:0)
您是否尝试过使用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 */
}
答案 3 :(得分:0)
使用“存储”属性,以及列的名称:
[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。
答案 4 :(得分:0)
我发现此问题的最佳解决方案是在类中创建一个私有Guid字段,该字段与数据库中的主键具有完全相同的名称,并将其用作符合该属性的属性的支持字段框架指南命名约定。
// 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;