简体   繁体   English

在.NET中存储业务值的位置 - SQL Server应用程序

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

This has always been an chicken and egg problem among developers. 这一直是开发人员的鸡和蛋问题。 Where do you store business values that are used within your application rules. 您在哪里存储应用程序规则中使用的业务值。 (In either ASP.NET, Window Forms or any data-driven application) (在ASP.NET,Window Forms或任何数据驱动的应用程序中)

I've seen people creating tables where they store text and value representation and then they link these records inside the code (by IDs or Text name). 我见过人们在创建表格时会存储文本和值表示,然后将这些记录链接到代码中(通过ID或文本名称)。 To me that's the worst possible way: 对我而言,这是最糟糕的方式:

  • you have to maintain the table and create administration module for each 你必须维护表并为每个创建管理模块
  • you have read the table every time you need to access business value 您每次需要访问业务价值时都已阅读该表
  • your application won't work without database being pre-filled - 如果没有预先填充数据库,您的应用程序将无法运行 -

And most developers tell me this the "best practice" which I'm not buying as it doesn't bring any benefit over approach where I place the business values directly to application like this: 大多数开发人员告诉我这是我不买的“最佳实践”,因为它没有带来任何好处,我把业务价值直接放到这样的应用程序:

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

A then use integer on the [Column] coming from/to the database which directly casts to Enum on the data object so the logic can directly say: 然后在[Column]上使用来自/到数据库的整数,它直接在数据对象上转换为Enum,因此逻辑可以直接说:

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

Which solves all the issues above but then when you run a report on the database outside of application you need to do the translation of these values in SQL. 这解决了上述所有问题,但是当您在应用程序之外运行数据库报表时,您需要在SQL中对这些值进行转换。

So I'm still wondering whether there is another "better" solution or pattern that developers use. 所以我仍然想知道开发人员是否还有其他“更好”的解决方案或模式。 I mean every data-driven application must have an approach/design to this problem which has been around ever since the beginning. 我的意思是每个数据驱动的应用程序必须有一个方法/设计来解决这个问题,这个问题从一开始就存在。

I'm not quite sure I agree with you that storing these values in an enum provides you all that much benefit over storing them in some sort of an external data source. 我不太确定我同意你的看法,将这些值存储在枚举中可以为你提供将它们存储在某种外部数据源中的所有好处。

you have to maintain the table and create administration module for each 你必须维护表并为每个创建管理模块

True, storing values in an external datasource does add some architectural overhead. 确实,将值存储在外部数据源中会增加一些架构开销。 However, if you're using any sort of an ORM to handle your data access and code generation this is a pretty minor endeavor. 但是,如果您使用任何类型的ORM来处理数据访问和代码生成,这是一个非常小的尝试。

I'm not sure what you mean by "administration module" but I'm going to assume that you mean a repository and not some interface for users to manage the options themselves. 我不确定你的“管理模块”是什么意思,但我会假设你的意思是一个存储库,而不是一些用户自己管理选项的界面。 I don't see why the latter would be required if the alternative is putting the values in an enum, since there's no way for users to manage those themselves either. 如果备选方案将值放在枚举中,我不明白为什么后者是必需的,因为用户也无法管理它们。

As far as "maintaining" the table goes, you don't really have to do any more maintenance than you would by adding or removing values from the enum. 就“维护”表而言,除了从枚举中添加或删除值之外,您实际上不需要进行任何维护。 As JonH points out, the enum route requires that you rebuild and redeploy your entire application, rather than simply adding or removing rows from a datasource. 正如JonH所指出的,枚举路由要求您重建和重新部署整个应用程序,而不是简单地在数据源中添加或删除行。 To me, that is a greater maintenance burden. 对我来说,这是一个更大的维护负担。

you have read the table every time you need to access business value 您每次需要访问业务价值时都已阅读该表

Not true, since I'm assuming these values are fairly static it's pretty trivial to cache these values at application start up and be done with it. 事实并非如此,因为我假设这些值是相当静态的,所以在应用程序启动时缓存这些值并完成它是非常简单的。

your application won't work without database being pre-filled 如果没有预先填充数据库,您的应用程序将无法运行

So what? 所以呢? If the application is data driven, it's going to require that deploying and configuring the database is part of the deployment plan. 如果应用程序是数据驱动的,则需要部署和配置数据库是部署计划的一部分。 Would adding 2 or 3 INSERT statements in a script add that much more complexity to the deployment process? 在脚本中添加2或3个INSERT语句会增加部署过程的复杂性吗?

Which solves all the issues above but then when you run a report on the database outside of application you need to do the translation of these values in SQL. 这解决了上述所有问题,但是当您在应用程序之外运行数据库报表时,您需要在SQL中对这些值进行转换。

Above all, this is the most compelling reason of all to store these values externally. 最重要的是,这是所有人在外部存储这些值的最有说服力的理由。 Given the fact these values are being used in reports means that they have meaning outside the scope of your application . 鉴于报告中使用这些值的事实意味着它们的含义超出了您的应用范围 This means that when they are needed elsewhere, you will have to duplicate this knowledge every time. 这意味着当他们需要在其他地方使用时,您每次都必须复制这些知识。 Any duplication in a system creates an additional maintenance burden and increases the chances for bugs to be introduced in future updates. 系统中的任何重复都会产生额外的维护负担,并增加在将来的更新中引入错误的机会。

Finally, Enums tend to be more difficult in databinding to UI elements. 最后,Enums在向UI元素进行数据绑定时往往更加困难。 When you can, they don't allow for "pretty" value names to be shown to the users. 如果可以,他们不允许向用户显示“漂亮”的值名称。 Instead they are shown dropdown boxes that contain items like "UserStoredFile" and "PickAndChooseAnotherEnumValue". 相反,它们会显示下拉框,其中包含“UserStoredFile”和“PickAndChooseAnotherEnumValue”等项目。 Outside of associating the enum values to separate strings (more duplication, see the above paragraph), there is no way to overcome this limitation of Enums. 除了将枚举值与单独的字符串相关联(更多重复,请参阅上面的段落)之外,没有办法克服Enums的这种限制。

While it seems like no big deal, any decent developer should care about little details like this. 虽然看起来没什么大不了的,但任何体面的开发者都应该关心这样的小细节。 Being concerned with the entire user experience is important. 关注整个用户体验非常重要。 Chances are, if you're not particularly detail-oriented there are probably plenty of other places in your system outside of UI that will also have problems. 有可能,如果你不是特别注重细节,你的系统中可能还有很多其他地方也会出现问题。 Admittedly, this last point is more of a subjective soapbox type of argument :). 不可否认,最后一点更像是主观的肥皂盒类型的论点:)。

I would agree with you that storing these values only does not nearly justify adding a database to your application. 我同意你的观点,只存储这些值并不能证明在应用程序中添加数据库是不合理的。 However, you'll notice I usually say external datasource . 但是,您会注意到我通常会说外部数据源 There's no reason you can't set up your application to pull these values from XML, or some other type of external configuration file. 您无法设置应用程序从XML或其他类型的外部配置文件中提取这些值。 However, if you've already got the database, you may as well keep it all in one place. 但是,如果您已经拥有数据库,那么您可以将它们保存在一个地方。

Edit: 编辑:

Using these objects is pretty straightforward, they're just collections. 使用这些对象非常简单,它们只是集合。 They databind much more naturally than enums, and I imagine in data-driven applications that's important: 它们比枚举更自然地数据绑定,我想在数据驱动的应用程序中这很重要:

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

Of course, like you mention this is certainly not impossible with enums, its just typically not as nice. 当然,就像你提到的那样,枚举肯定不是不可能的,它通常不那么好。

Making these "business values" into full fledged objects over enums also allows you greater flexibility for the future, should the concept of a SourceLocation ever need to grow beyond a name and an ID. 如果SourceLocation的概念需要超越名称和ID,那么通过枚举将这些“业务价值”转化为完整的对象也可以为未来提供更大的灵活性。

Lets imagine that later an 'IsRemote' property is added to the SourceLocation, to denote that the location resides on a separate machine. 让我们假设稍后将“IsRemote”属性添加到SourceLocation,以表示该位置驻留在单独的计算机上。 SourceLocation now is able to accommodate rules that require this property: SourceLocation现在能够容纳需要此属性的规则:

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

You also would be able to filter down the collection of SourceLocation by this property, in case you had some code that required all locations where IsRemote is true: 如果您的某些代码需要IsRemote为true的所有位置,您还可以通过此属性过滤SourceLocation集合:

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

However, enums do have a distinct advantage over data-driven objects in one respect, and that is when they are used as application constants. 但是,在一个方面,枚举确实比数据驱动对象具有明显的优势,那就是它们被用作应用程序常量。 In fact that is all an enum really is, a group of constants. 事实上,这就是一个真正的枚举,一组常数。 It is more difficult to effectively write a rule against a static value when it is implemented as a dynamic, data-driven one. 当将规则实现为动态的,数据驱动的规则时,更有效地针对静态值编写规则。

In the case of your specific example this is true. 在您的具体示例的情况下,这是真的。 All your rule is really saying is "If source location == 1, then do this." 您的所有规则都是“如果源位置== 1,那么就这样做”。 I would never want a bunch of magic ints floating around my application, so I would most certainly define an enum like the one you have above . 我永远不会想要在我的应用程序中浮动一堆魔术,所以我肯定会定义一个类似你上面的枚举。

Does this mean that in this case I would use an enum only and forgo persisting the value in an external datasource? 这是否意味着在这种情况下我只使用枚举并放弃在外部数据源中保存值? Not necessarily, it all depends on how the particular values are being used within the context of the system. 不一定,这一切都取决于在系统环境中如何使用特定值。 In your example, theses values appear to have significance in the domain as a whole, not just a single application. 在您的示例中,这些值似乎在整个域中具有重要性,而不仅仅是单个应用程序。 You've described them as "business values" and mentioned that they are used in other applications such as reporting. 您已将它们描述为“业务价值”,并提到它们用于其他应用程序,例如报告。 To me, this would make it totally appropriate to provide a central location from which this knowledge can be shared, and I would persist them in addition to defining them in an enum. 对我来说,这将使得提供一个可以共享这些知识的中心位置是完全合适的,除了在枚举中定义它们之外,我会坚持它们。

You might say, "Wait.. isn't THAT duplication? Isn't that bad?" 你可能会说,“等等......不是重复吗?不是那么糟糕吗?” Well yes, but no less then you would have had using the enum-only route and you still gain the design bonuses of designing your business values as full-fledged domain objects. 是的,但不会少于你使用仅枚举路线,你仍然可以获得设计业务价值的设计奖金作为完整的域对象。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM