简单的数据库设计和LINQ

时间:2010-05-10 23:32:53

标签: c# xml linq database-design

我在设计数据库方面经验很少,现在我想创建一个非常简单的数据库,它与我以前在xml中所做的一样。这是xml:

<services>
  <service type="writing">
    <small>125</small>
    <medium>100</medium>
    <large>60</large>
    <xlarge>30</xlarge>
  </service>
  <service type="analysis">
    <small>56</small>
    <medium>104</medium>
    <large>200</large>
    <xlarge>250</xlarge>
  </service>
</services>

现在,我想在SQL数据库中创建相同的东西,并开始这样做(希望这格式好,但你会得到要点,四列和两行):

> ServiceType Small Medium Large
> 
> Writing       125    100    60
> 
> Analysis       56    104   200

这不太好用,因为我之后想用LINQ来选择写作的大值(60)。但我不能使用LINQ(据我所知)并使用变量作为大小(参见下面方法中的参数)。我只能这样做,如果我有一个像“大小”这样的列,其中Small,Medium和Large就是值。但是这也感觉不对,因为那时我会得到几行ServiceType = Writing(在这种情况下为3,每个大小为1),而Analysis也是如此。如果我要添加更多服务类型,我将不得不这样做。简单重复......是否有任何聪明的方法可以使用关系或其他方式来做到这一点?

使用上面的第二个设计(虽然不好),我可以使用以下LINQ来选择一个带参数的值:

protected int GetHourRateDB(string serviceType, Size size)
{
  CalculatorLinqDataContext context = new CalculatorLinqDataContext();
  var data = (from calculatorData in context.CalculatorDatas
        where calculatorData.Service == serviceType && calculatorData.Size == size.ToString()
        select calculatorData).Single();
  return data.Hours;
}

但如果还有其他更好的设计,请问您还可以描述如何使用LINQ进行相同的选择吗?

请记住,我是数据库设计的新手,所以请尽可能明确和教学: - )

谢谢!

的Anders

2 个答案:

答案 0 :(得分:2)

您可以使用第一种方法并执行以下操作:

protected int GetHourRateDB(string serviceType, Size size)
{
    using (CalculatorLinqDataContext context = new CalculatorLinqDataContext())
    {
        var data =
            (from calculatorData in context.CalculatorDatas
            where calculatorData.Service == serviceType
            select calculatorData).Single();

        switch (size) {
            case Small:
                return data.Small;
            case Medium:
                return data.Medium;
            case Large:
                return data.Large;
            default:
                // Error handling
         }
     }
}

你的第二种方法也可以,但如果你知道所有项目总会有三种尺寸,并且它们将永远被称为小型,中型和大型,那么通过使用第一种方法,您可以将其硬编码为架构并让数据库为您强制执行。

您可能还想考虑使用自动递增主键而不是使用服务名称作为主键是否更好。姓名有一个不幸的问题,他们经常因为你无法控制的原因而改变(修正错别字,营销,翻译等)。您可能希望避免每次名称更改时重新编译程序。

答案 1 :(得分:1)

如果您想使用枚举来选择所需的字段,请转到Mark Byers答案。我只想展示另一种方法来做你想做的事情:只需使用lambda来选择字段,就像你在许多其他Linq方法中所做的那样:

protected int GetHourRateDB(string serviceType, 
                            Func<CalculatorData, int> fieldSelector)
{
    using(CalculatorLinqDataContext context = new CalculatorLinqDataContext())
    {
        return fieldSelector(
                  (from calculatorData in context.CalculatorDatas
                   where calculatorData.Service == serviceType
                   select calculatorData).Single()
               );
    }
}

您可以使用它:

int someSmallValue = GetHourRateDB("Writing", x => x.Small);
int someMediumValue = GetHourRateDB("Writing", x => x.Medium);

请注意,如果数据库中没有包含给定serviceType的元素,Single()将抛出InvalidOperationException。你必须以某种方式处理它。