在 switch 语句中使用标识字段

发布于 2024-08-05 18:22:38 字数 522 浏览 8 评论 0原文

我有一个像这样的 SQL 查找表:

CREATE TABLE Product(Id INT IDENTITY PRIMARY KEY, Name VARCHAR(255))

我已将 ASP.NET DropDownList 数据绑定到 LLBLGen 实体。用户选择一个产品,并且 ID 被保存。现在我需要稍后显示一些产品特定的详细信息。我是否应该使用产品的 ID,并希望 ID 在安装之间始终相同?

switch (selectedProduct.Id)
{
case 1: //product one
  break;
case 2:
case 3: //product two or three
  break;    
}

或者使用这个名字,并希望永远不会改变?

switch (selectedProduct.Name)
{
case "product one":
  break;    
}

或者有更好的选择吗?

I have a SQL lookup table like this:

CREATE TABLE Product(Id INT IDENTITY PRIMARY KEY, Name VARCHAR(255))

I've databound a ASP.NET DropDownList to a LLBLGen entity. User selects a product, and the Id get saved. Now I need to display some product specific details later on. Should I use the Product's ID, and hope the ID is always the same between installations ?

switch (selectedProduct.Id)
{
case 1: //product one
  break;
case 2:
case 3: //product two or three
  break;    
}

or use the name, and hope that never changes?

switch (selectedProduct.Name)
{
case "product one":
  break;    
}

Or is there a better alternative?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

回梦 2024-08-12 18:22:39

一些 ORM(至少 LLBLGen)可以为您处理这个问题;但生成强类型的枚举。不过我从来没有用过那个。

在这些情况下,我总是只使用我自己编写的枚举,但我确保所有字段都相同,并在发生任何更改时进行更新。当您跨数据库工作时(就像我一样),它会变得更有趣,但如果您小心的话,它就足够简单了。

Some ORMs (LLBLGen at least) can handle this for you; but generating a strong type of enums. I've never used that though.

In these cases, I always just go with an enum that I write myself, but I make sure that all the fields are equal, and update if any change. It becomes more interesting when you work across databases (as I do), but if you take care, it is simple enough.

庆幸我还是我 2024-08-12 18:22:38

如果您知道此表中的所有项目(我想如果您可以对它们进行切换,您就会知道)并希望每次安装它们都相同,那么也许它不应该是标识列,您应该插入 1, 2, 3、与产品本身有关。

If you know of all the items in this table (which I guess you do if you can do a switch on them) and want them the same for each installation then maybe it should not be an identity column and you should insert 1, 2, 3 with the products themselves.

恍梦境° 2024-08-12 18:22:38

对于这种情况,我见过三种常见的解决方案:

  1. 对 ID 进行硬编码 - 这是快速且肮脏的,不是自记录的(您不知道正在引用什么产品),以及正如您所指出的,容易破裂。我再也不用这个方法了。
  2. 枚举 - 当表很小且静态时我使用它。因此,ProductType 可能是一个候选者。这是自记录代码,但仍然在代码和数据之间创建了一个尴尬的连接,如果插入的记录的 ID 与您计划的不同,那么事情就会中断。您可以通过各种方式自动生成枚举来缓解这种情况,但仍然感觉不对。例如,如果您的单元测试将记录插入到 Product 表中,那么他们将很难在此时重新创建 Enum。另外,如果您有 100,000 条记录,则 Enum 方法开始看起来非常愚蠢。
  3. 添加附加列,这是一个不变的标识符。我经常使用 AlphaCode 作为我的列名。所以在你的情况下它看起来像:

    switch (selectedProduct.AlphaCode)
    {
        case "PRODUCT_ONE":
            break;
}

This lets you use an AlphaCode that is self-documenting, allows you to reinsert data without caring about the autoincrement PK value, and lets you change the product name without affecting anything. If you use the AlphaCode approach, ensure that you put a unique index on this column.

另一种解决方案(通常是最可取的)是将此逻辑移至数据库。例如,如果产品 1 是您在选择其类别时始终希望默认显示的产品,则可以向表中添加一个名为 IsHeroProduct 的列。那么你的查询就变成:

    if (selectedProduct.IsHeroProduct)
    {
        //do stuff
}

For this situation, there are three common solutions I have seen:

  1. Hard code the ID - this is quick and dirty, not self-documenting (you don't know what product is being referred to), and prone to breakage as you pointed out. I never use this method anymore.
  2. Enums - I use this when the table is small and static. So, ProductType would be a possible candidate for this. This is self-documenting code, but still creates an awkward connection between code and data where if records are inserted with different IDs than you planned for, then things break. You can mitigate this by automating the Enum generation in various ways, but it still feels wrong. E.g., if your unit tests are inserting records into the Product table, it will be difficult for them to recreate the Enum at that point. Also, if you have 100,000 records, the Enum approach starts to look pretty dumb.
  3. Add an additional column, that is a non-changing identifier. I often use AlphaCode as my column name. So in your case it would look like:

    switch (selectedProduct.AlphaCode)
    {
        case "PRODUCT_ONE":
            break;
}


This lets you use an AlphaCode that is self-documenting, allows you to reinsert data without caring about the autoincrement PK value, and lets you change the product name without affecting anything. If you use the AlphaCode approach, ensure that you put a unique index on this column.

The other solution, which is often the most preferable one, is to move this logic to the database. E.g., if product 1 is the product you always want to show by default when its category is selected, you could add a column to your table called IsHeroProduct. Then your query becomes:

    if (selectedProduct.IsHeroProduct)
    {
        //do stuff
}

睡美人的小仙女 2024-08-12 18:22:38

如果您希望固定 ProductID(这似乎不是一个好主意),那么您可以使用 IDENTITY INSERT(至少在 SQL Server 中)来确保 ProductID 值在装置。但是,我通常只会对静态参考数据执行此操作。

您还可以使用 Visual Studio 的 T4 模板直接从数据库数据生成枚举

If you want your ProductID's to be fixed (which doesn't seem to be a good idea), then you can use IDENTITY INSERT (in SQL Server, at least) to ensure ProductID values are the same between installations. But, I would normally only do this for static reference data.

You can also use Visual Studio's T4 templates to generate enums directly off the database data

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文