我正在使用.net版本4.5.2和Oracle DB开发一个C#应用程序。
我遇到的问题是我无法将Entity Framework配置为数据库。该数据库包含4列以上的唯一键,但其中2列可以为空。
[Key, Column("GEBRUIKER", Order = 0)]
public string User { get; set; }
[Key, Column("EL1", Order = 1)]
public string Element1 { get; set; }
[Key, Column("EL2", Order = 2)]
public short? Element2 { get; set; }
[Key, Column("EL3", Order = 3)]
public short? Element3 { get; set; }
当我尝试通过数据库中的代码获取值时,我得到一个空引用异常,因为元素2或3是空的。
当我从元素2和3中删除键时,我不会得到正确的数据,因为当元素1在2行时相同时,第二行将缓存元素2和3。
问题:如何处理这些可以为空的唯一键?
添加了额外信息:
嗯,这是数据库创建脚本的一部分:
CREATE TABLE USERS
(
GEBRUIKER VARCHAR2(3 BYTE) NOT NULL,
EL1 VARCHAR2(6 BYTE) NOT NULL,
EL2 NUMBER,
EL3 NUMBER
)
CREATE UNIQUE INDEX USERS_UK ON USERS
(GEBRUIKER, EL1, EL2, EL3)
ALTER TABLE USERS ADD (
CONSTRAINT USERS_UK
UNIQUE (GEBRUIKER, EL1, EL2, EL3)
USING INDEX USERS_UK
ENABLE VALIDATE);
无法对结构或数据进行任何更改,因为有多个应用程序使用此数据库。此外,已有EL2和EL3行的值为0.
示例数据:
{'USER1','A','A','C'}
{'USER1','A','B','B'}
{'USER1','B','A','C'}
当我执行linq查询以选择USER1 AND EL1 = A时,我将得到下一个结果:
{'USER1','A','A','C'}
{'USER1','A','A','C'}
而不是:
{'USER1','A','A','C'}
{'USER1','A','B','B'}
答案 0 :(得分:1)
不,你不能这样做:
查看表创建SQL:
CREATE TABLE [dbo].[Users](
[GEBRUIKER] [nvarchar](128) NOT NULL,
[EL1] [nvarchar](128) NOT NULL,
[EL2] [smallint] NOT NULL,
[EL3] [smallint] NOT NULL,
CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED
(
[GEBRUIKER] ASC,
[EL1] ASC,
[EL2] ASC,
[EL3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
所有主键都是非空 !!!!
假设您想要破解此密钥并使用SQL自行更改它,然后您必须发送以下脚本,这将把密钥从nun nullable更改为nullabe!
usersDatabaseContext.Database.ExecuteSqlCommand(@"
while(exists(select 1 from INFORMATION_SCHEMA.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY'))
begin
declare @sql nvarchar(2000)
SELECT TOP 1 @sql=('ALTER TABLE ' + TABLE_SCHEMA + '.[TableName] DROP CONSTRAINT [' + CONSTRAINT_NAME + ']')
FROM information_schema.table_constraints
WHERE CONSTRAINT_TYPE = 'FOREIGN KEY'
exec (@sql)
end
ALTER TABLE Users DROP CONSTRAINT [PK_dbo.Users]
ALTER TABLE Users ALTER COLUMN EL2 SMALLINT NULL
ALTER TABLE Users
ADD CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED ( [GEBRUIKER] ASC, [EL1] ASC, [EL2] ASC, [EL3] ASC )",
TransactionalBehavior.DoNotEnsureTransaction);
var user1 = new User { UserName = "Bassam", Element1 = "1", Element2 = null, Element3 = 3 };
我有:
- Removed all foreign keys which are related to this table
- Dropped the primary key
- Changed the **Column E2 to nullable**
- Adding the modified primary key again
如果是SQL Server,这将导致SQL Server / Oracle DB中出现以下错误: 无法在“用户”表中的可为空的列上定义PRIMARY KEY约束。
要好好考虑一下,即使你说你可以用你的主键做到这一点:
您如何保证PRIMARY密钥的唯一性?假设您的用户实体将创建以下行:
Id1 Id2 Id3 , Id4
"a" , "a" , null , null
您无法再次创建相同的条目,因为该行将存在于表中!