對此的道歉很長,但我看到太多的問題,包括太少的信息......如果有人在前幾行看到我的錯誤,我會很高興。 ..SqlConnection忽略用戶的默認模式
我有一個SQL Server 2008 R2數據庫,並且無法通過C#SqlConnection連接時得到我認爲應該是正確的行爲。
我用Visual C#2010速成建了兩個C#應用程序:
- 一個用於數據導入/導出/報表和瀏覽
- 一個用於做一些複雜的處理
這是所有在所有更新等Windows 7上...
這些兩個應用程序中的每一個使用的一些表是共享的公用表,並且其他需要保持s eparated。由於我需要能夠在雙方之間轉換和傳輸數據,因此我想將所有這些保存在一個數據庫中。
要保持一定程度的分離,我已經創建了兩個模式,兩個用戶,兩個角色和兩次登錄,如:
CREATE LOGIN [Import_User] WITH PASSWORD=N'*****'
CREATE LOGIN [Engine_User] WITH PASSWORD=N'*****'
CREATE USER [Import_User] FOR LOGIN [Import_User] WITH DEFAULT_SCHEMA=[Import_Schema]
CREATE USER [Engine_User] FOR LOGIN [Engine_User] WITH DEFAULT_SCHEMA=[Engine_Schema]
CREATE ROLE [Import_Role] AUTHORIZATION [dbo]
CREATE ROLE [Engine_Role] AUTHORIZATION [dbo]
EXEC('CREATE SCHEMA [Import_Schema] AUTHORIZATION [Import_User]')
EXEC('CREATE SCHEMA [Engine_Schema] AUTHORIZATION [Engine_User]')
-- Import role permissions on the Import schema
GRANT EXECUTE, DELETE, INSERT, SELECT, UPDATE, REFERENCES ON SCHEMA::[Import_Schema] TO [Import_Role]
-- Engine_Role permissions on the engine schema
GRANT EXECUTE, DELETE, INSERT, SELECT, UPDATE, REFERENCES ON SCHEMA::[Engine_Schema] TO [Engine_Role]
EXEC sp_addrolemember N'Import_Role', N'Import_User'
EXEC sp_addrolemember N'Engine_Role', N'Engine_User'
GRANT CONNECT TO [Import_User]
GRANT CONNECT TO [Engine_User]
然後,我創建在每個模式的一些表和存儲的特效,適當到每個角色。引擎架構中可能有20個表,導入架構中有30個左右。其中有些是在兩個模式非常相似,但並不完全相同,如:
CREATE TABLE [Engine_Schema].[Problem](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Description] [varchar](max) NULL,
CONSTRAINT [PK_Status] PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCK = ON) ON [PRIMARY])
ON [PRIMARY]
CREATE TABLE [Import_Schema].[Problem](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Name] [varchar](50) NOT NULL,
[Client] [varchar](50) NOT NULL,
[Description] [varchar](max) NULL,
CONSTRAINT [PK_Status] PRIMARY KEY CLUSTERED ([ID] ASC)
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCK = ON) ON [PRIMARY])
ON [PRIMARY]
這一切似乎正常工作時,是否使用這兩個登錄通過SSMS - 每次登錄時看到的完全表和SP我期望的。在每種情況下,我都可以在SSMS中運行查詢和USP,而無需使用模式前綴,因爲這些連接使用我爲每個登錄/用戶設置的默認模式。如果我登錄爲'sa',那麼我當然可以在兩種模式中看到所有內容。
在我的C#代碼,我連接到數據庫這樣的:
SqlConnection dbConnection = new SqlConnection(""server=laptop; database=test; user id=Engine_User; password=*****; Trusted_Connection=yes; connection timeout=30");
dbConnection.Open();
然後我嘗試直接查詢數據庫中的表是這樣的:
using (SqlCommand cmdSelectProblems = new SqlCommand()) {
cmdSelectProblems.Connection = dbConnection;
cmdSelectProblems.CommandText = "Select ID, Name from Problem order by Name";
DataTable dataTableProblems = new DataTable();
using (SqlDataAdapter dataAdapterProblems = new SqlDataAdapter(cmdSelectProblems)) {
dataAdapterProblems.Fill(dataTableProblems);
...
或者我可以嘗試使用一個我的存儲過程是這樣的:
using (SqlCommand cmd = new SqlCommand()) {
cmd.Connection = dbConnection;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "SelectProblems";
using (SqlDataAdapter da = new SqlDataAdapter(cmd))
da.Fill(_problemsTable);
}
但是,當我嘗試通過我的C#代碼使用連接像這些e xamples,我得到這樣的錯誤:
Invalid object name 'Problem'
或
Could not find stored procedure 'SelectProblems'
我似乎需要使用顯式模式前綴以訪問數據庫中的那些相同的數據庫對象。隨着模式的前綴明確包含東西從我的C#代碼,據我已經測試了他們所有的工作,所以直接表查詢更改爲:
cmdSelectProblems.CommandText = "Select ID, Name from [Engine_Schema].Problem order by Name";
或嘗試用類似的模式前綴訪問賣點:
cmd.CommandText = "[Engine_Schema].SelectProblems";
然後一切正常。
現在我知道使用顯式模式名稱是最好的做法,但我有一個C#和作爲存儲過程中不使用這些模式前綴編寫的代碼整體卸載。如果我可以使C#SqlConnection
查詢尊重我已定義和使用的登錄的默認架構,那將會非常簡單。我相信這應該能夠正常工作,但我想我一定錯過了某個地方。
迄今爲止我已經浪費了兩天時間,而且我所讀到的所有內容都表明,這應該都是正常的。
賓果 - 知道了。不知道爲什麼我之前沒有嘗試過 - 我認爲設置用戶ID和密碼而不是我更常用的Windows身份驗證字符串就足夠了。 – TimChippingtonDerrick 2013-02-25 20:54:24