2011-05-17 38 views
1


在我的應用程序中,我有像User,Person和Group這樣的IMember類型的實體(因爲它們可以是某個用戶組的成員)。在我的MS SQL 2008數據庫中還有用戶,個人和組表,這些表保存相應的實體數據。
我經常需要將所有這些實體或實體集合作爲一個集合 - 例如,當我獲得某個組的所有成員,或者我正在通過他們的名字或其他名稱搜索成員時。爲此,我希望有一個應用程序方法,其中對應於IMember類型的所有表格都已確定(將來可能會添加一些表格)。這個函數應該返回一個集合中的所有被檢索的對象,並且我還希望該函數接受一些條件來爲每個表執行所需的請求,因爲我將有一些更具體的函數調用上述。例如,如果我想要獲取所有IMember的名稱是「nick」,則該函數應在User,Person和Group表中搜索「nick」。傳遞這些條件並保持最終SQL查詢最佳的最佳方式是什麼?
謝謝!Tricky LINQ函數

回答

0

首先,我想按照我的理解重新表達您的問題。你有一些表格中類似下面的數據庫:

--SQL DDL 
CREATE TABLE [User](
    Name varchar(25), 
    Location varchar(50) 
    --Other User specific columns like login, expireDate etc. 
) 

CREATE TABLE Person(
    Name varchar(25), 
    Location varchar(50) 
    --Other Person specific columns like Birthday etc. 
) 

的表都有基地組代表成員列。在代碼中,你有一個像這樣定義的接口。 (你在C#或VB工作?)

//C# code 
interface IMember 
{ 
    string Name { get; set; } 
    string Location { get; set; } 
} 

'VB code 
Interface IMember 
    Property Name As String 
    Property Location As String 
End Interface 

你想做些什麼是對所有IMembers作爲一個單一的邏輯集合操作。有關任何限制或偏好的更多信息可能會很好,例如:是否可行/是否有權更改數據庫的佈局?您能否將存儲過程添加到數據庫以便於對集合進行操作?它只是選擇你需要的成員,還是你需要能夠插入/更新/刪除成員?將新的派生成員表添加到數據庫時,是否需要用最少量的更改重新編譯代碼?此外,如果您打算要求提供可能包含代碼片段的解決方案,那麼很高興知道您選擇哪種.NET語言。對於許多人來說,「最優」對許多人來說意義非凡,在代碼方面最簡單?最快的?最少的往返旅程?是真正的最佳真正的要求還是有一個「夠好」?

也就是說,這裏有一些可能的解決方案

可能的解決辦法#1: 你可以調整你的表像這樣:

--SQL DDL 
CREATE TABLE Member(
    MemberID int PRIMARY KEY, 
    Name varchar(25) 
    Location varchar(50) 
) 

CREATE TABLE User(
    MemberID int FOREIGN KEY, 
    --Other User specific columns like login, expireDate etc. 
) 

CREATE TABLE Person(
MemberID int FOREIGN KEY, 
    --Other Person specific columns like Birthday etc. 
) 

有了新的結構,你的問題就變得簡單。您可以使用linq-to-sql在成員表上使用SELECT,UPDATE,DELETE(使用級聯刪除設置)。任何後來添加的新表都將遵循與具有外鍵的成員表加入相同的形式,並且任何應用程序都不需要重新編譯。如果這不是一個可能的解決方案,請解釋原因。

可能的解決方案#2 讓我們假設由於遺留問題或權限問題而無法完成上述操作。是否有可能設置視圖或存儲過程來模擬上述解決方案。類似下面的存儲過程可以讓你按名稱選擇所有成員。插入/更新/刪除可能會更復雜,如果他們需要。

CREATE PROCEDURE GetMemberByName @Name varchar(25) AS 
BEGIN 
     SELECT Name, Location FROM [User] 
    UNION SELECT Name, Location FROM Person 
    --Add more tables here when available 
    WHERE NAME = @Name 
END 

同樣,這是一個解決方案,當添加新表時,您不需要重新編譯代碼。

可能的解決方案#3 最後,一個代碼內解決方案可能更符合您的需求。我關於細節的問題也是相關的。當添加一個新表時,你是否要重新編譯你的L2S類?如果是的話,您可以將IMember接口添加到每個表類中,然後在派生的datacontext的部分類中公開所提供的所有表的.Concat()的部分類中的屬性。如果不是,則可能必須查詢數據庫系統表以使所有表都具有所有必需的IMember屬性作爲列,然後選擇它們的聯合。這似乎很多工作,如果你必須走這條路,我不會嫉妒你。

此外,將更新/插入/刪除回寫到適當的表的可能要求可能必須遍歷可能的表以更改正確的表。表中有一個關鍵是uniq w.r.t.所有成員表。這是GUID發光的一個很好的例子,因爲如果你有一個名字爲Joe的用戶和一個名字爲Joe的用戶,並且他們碰巧有相同的代理鍵1234,那麼一旦該實體在一個集合中IMember,你怎麼知道要更新/插入/刪除?

摘要對不起,如果我聽起來像是在挑剔地詢問更多細節,但對於人們回答具體明確的問題真的很容易。請嘗試詳細說明您的問題,或將其分解爲更小的問題,這些問題可以更具體地回答。將相關的DDL添加到您知道不讓我們猜測的現有表格中,以及您可能已經嘗試的相關代碼片段。當人們看到他們可以使用的代碼塊來幫助您改進代碼塊時,它會撿起更多的眼睛。