簡體   English   中英

在.NET中存儲業務值的位置 - SQL Server應用程序

[英]Where to store business values in .NET - SQL Server applications

這一直是開發人員的雞和蛋問題。 您在哪里存儲應用程序規則中使用的業務值。 (在ASP.NET,Window Forms或任何數據驅動的應用程序中)

我見過人們在創建表格時會存儲文本和值表示,然后將這些記錄鏈接到代碼中(通過ID或文本名稱)。 對我而言,這是最糟糕的方式:

  • 你必須維護表並為每個創建管理模塊
  • 您每次需要訪問業務價值時都已閱讀該表
  • 如果沒有預先填充數據庫,您的應用程序將無法運行 -

大多數開發人員告訴我這是我不買的“最佳實踐”,因為它沒有帶來任何好處,我把業務價值直接放到這樣的應用程序:

public enum SourceLocation
        {
            Database = 0,
            File = 1,
            UserInput = 3        
        }

然后在[Column]上使用來自/到數據庫的整數,它直接在數據對象上轉換為Enum,因此邏輯可以直接說:

if(DataObject.Column == SourceLocation.File)
       //Read From File

這解決了上述所有問題,但是當您在應用程序之外運行數據庫報表時,您需要在SQL中對這些值進行轉換。

所以我仍然想知道開發人員是否還有其他“更好”的解決方案或模式。 我的意思是每個數據驅動的應用程序必須有一個方法/設計來解決這個問題,這個問題從一開始就存在。

我不太確定我同意你的看法,將這些值存儲在枚舉中可以為你提供將它們存儲在某種外部數據源中的所有好處。

你必須維護表並為每個創建管理模塊

確實,將值存儲在外部數據源中會增加一些架構開銷。 但是,如果您使用任何類型的ORM來處理數據訪問和代碼生成,這是一個非常小的嘗試。

我不確定你的“管理模塊”是什么意思,但我會假設你的意思是一個存儲庫,而不是一些用戶自己管理選項的界面。 如果備選方案將值放在枚舉中,我不明白為什么后者是必需的,因為用戶也無法管理它們。

就“維護”表而言,除了從枚舉中添加或刪除值之外,您實際上不需要進行任何維護。 正如JonH所指出的,枚舉路由要求您重建和重新部署整個應用程序,而不是簡單地在數據源中添加或刪除行。 對我來說,這是一個更大的維護負擔。

您每次需要訪問業務價值時都已閱讀該表

事實並非如此,因為我假設這些值是相當靜態的,所以在應用程序啟動時緩存這些值並完成它是非常簡單的。

如果沒有預先填充數據庫,您的應用程序將無法運行

所以呢? 如果應用程序是數據驅動的,則需要部署和配置數據庫是部署計划的一部分。 在腳本中添加2或3個INSERT語句會增加部署過程的復雜性嗎?

這解決了上述所有問題,但是當您在應用程序之外運行數據庫報表時,您需要在SQL中對這些值進行轉換。

最重要的是,這是所有人在外部存儲這些值的最有說服力的理由。 鑒於報告中使用這些值的事實意味着它們的含義超出了您的應用范圍 這意味着當他們需要在其他地方使用時,您每次都必須復制這些知識。 系統中的任何重復都會產生額外的維護負擔,並增加在將來的更新中引入錯誤的機會。

最后,Enums在向UI元素進行數據綁定時往往更加困難。 如果可以,他們不允許向用戶顯示“漂亮”的值名稱。 相反,它們會顯示下拉框,其中包含“UserStoredFile”和“PickAndChooseAnotherEnumValue”等項目。 除了將枚舉值與單獨的字符串相關聯(更多重復,請參閱上面的段落)之外,沒有辦法克服Enums的這種限制。

雖然看起來沒什么大不了的,但任何體面的開發者都應該關心這樣的小細節。 關注整個用戶體驗非常重要。 有可能,如果你不是特別注重細節,你的系統中可能還有很多其他地方也會出現問題。 不可否認,最后一點更像是主觀的肥皂盒類型的論點:)。

我同意你的觀點,只存儲這些值並不能證明在應用程序中添加數據庫是不合理的。 但是,您會注意到我通常會說外部數據源 您無法設置應用程序從XML或其他類型的外部配置文件中提取這些值。 但是,如果您已經擁有數據庫,那么您可以將它們保存在一個地方。

編輯:

使用這些對象非常簡單,它們只是集合。 它們比枚舉更自然地數據綁定,我想在數據驅動的應用程序中這很重要:

// Bind a collection of SourceLocation to an ASP.net dropdown list
ddlSourceLocations.Datasource = GetSourceLocations();
ddlSourceLocations.DataTextField = "LocationName";
ddlSourceLocations.DataValueField = "LocationId";
ddlSourceLocations.DataBind();

當然,就像你提到的那樣,枚舉肯定不是不可能的,它通常不那么好。

如果SourceLocation的概念需要超越名稱和ID,那么通過枚舉將這些“業務價值”轉化為完整的對象也可以為未來提供更大的靈活性。

讓我們假設稍后將“IsRemote”屬性添加到SourceLocation,以表示該位置駐留在單獨的計算機上。 SourceLocation現在能夠容納需要此屬性的規則:

if(myDataObject.SourceLocation.IsRemote) {
    // If the location is remote, do something extra   
}

如果您的某些代碼需要IsRemote為true的所有位置,您還可以通過此屬性過濾SourceLocation集合:

var remoteLocations = GetSourceLocations().Where(x => x.IsRemote);

但是,在一個方面,枚舉確實比數據驅動對象具有明顯的優勢,那就是它們被用作應用程序常量。 事實上,這就是一個真正的枚舉,一組常數。 當將規則實現為動態的,數據驅動的規則時,更有效地針對靜態值編寫規則。

在您的具體示例的情況下,這是真的。 您的所有規則都是“如果源位置== 1,那么就這樣做”。 我永遠不會想要在我的應用程序中浮動一堆魔術,所以我肯定會定義一個類似你上面的枚舉。

這是否意味着在這種情況下我只使用枚舉並放棄在外部數據源中保存值? 不一定,這一切都取決於在系統環境中如何使用特定值。 在您的示例中,這些值似乎在整個域中具有重要性,而不僅僅是單個應用程序。 您已將它們描述為“業務價值”,並提到它們用於其他應用程序,例如報告。 對我來說,這將使得提供一個可以共享這些知識的中心位置是完全合適的,除了在枚舉中定義它們之外,我會堅持它們。

你可能會說,“等等......不是重復嗎?不是那么糟糕嗎?” 是的,但不會少於你使用僅枚舉路線,你仍然可以獲得設計業務價值的設計獎金作為完整的域對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM