3

我有两个示例表:

场景 1

表 1 - 成分

ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)

表 2 - 成分附加信息

ingredientAdditionalInformationId(PK, int, not null)
ingredientId(FK, int, not null)
isApproved(bit, not null)
unitsConverted(bit, not null)

在代码后面选择句子:

public IQueriable GetIngredientData(int ingredientId)
{
  using (var context = new MyEntities())
  {
      var result = context.Ingredient
            .Where(i => i.ingredientId == ingredientId)
            .Select(i => new
            {
                 i.ingredientId,
                 i.userId
                 i.IngredientAdditionalInformation.FirstOrDefault(iai => iai.ingredientId = i.ingredientId).isApproved
                 i.IngredientAdditionalInformation.FirstOrDefault(iai => iai.ingredientId = i.ingredientId).unitsConverted
             });

          return result.ToList().AsQueriable();
  }
}

或使用联接选择(我知道您可以使用方法语法联接,但我可以更快地使用查询方法编写联接)

public IQueriable GetIngredientData(int ingredientId)
{
  using (var context = new MyEntities())
  {
       var result = from i in context.Ingredient
            join iai in context.IngredientAdditionalInformation on i.ingredientId equals iai.ingredientId
            where i.ingredientId == 1
            select new
            {
                 i.ingredientId,
                 i.userId
                 iai.isApproved
                 iai.unitsConverted
            };         

        return result.ToList().AsQueriable();
  }
}

使用 join 或 FirstOrDefault() 哪个更好/更快,或者我应该编写不同的数据库表,如下例 2 所示:

情景 2

表 1 - 成分

ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)

表 2 - 成分

ingredientId(PK, FK, int, not null) //WITHOUT PRIMARY (ingredientAdditionalInformationId) AUTO INCREMENT KEY)
isApproved(bit, not null)
unitsConverted(bit, not null)

因为我知道每种成分只有一个附加信息...

在代码中选择句子

using (var context = new MyEntities())
{
    var result = context.Ingredient
      .Where(i => i.ingredientId = 1)
      .Select(i => new
      {
           i.ingredientId,
           i.userId
           i.IngredientAdditionalInformation.isApproved
           i.IngredientAdditionalInformation.unitsConverted
       });
} 

我想知道哪种表设计更适合优化选择(SCENARIO1 或 SCENARIO2),如果我真的需要在成分AdditionalInformation 中自动递增键,如果我知道每种成分只有一个条目并且这是正确的使用方式实体框架?

4

2 回答 2

2

如果您要维护两个表之间的一对一关系,那么您的第二种设计会更好,因为它还将确保数据库中的引用完整性。

然后,您可以将该属性作为实体框架模型中的单个导航属性,并按如下方式简化您的 EF 查询。如果您在模型中启用了导航属性的延迟加载,则您可能无需使用包含就可以逃脱,如果您是

var result = from i in context.Ingredient.Include("IngredientAdditionalInformation") select i;

然后按如下方式访问属性:

i.IngredientAdditionalInformation.isApproved

但是,您真的需要一张额外的桌子吗?每个只有三个属性,我只需将它们组合到一个表中,然后您就可以立即获得所有可用的属性。

于 2013-10-10T14:40:33.853 回答
2

方案 2 更好,因为您说两个表之间存在一对一的关系。
您应该探索的另一个选项是使用 Table Per Type Inheritance。在这种情况下,您不需要使用 Include 或 joins 指定预先加载。

假设您的 table1 = IngredientBase 和 table2 = Ingredients 并且在您的上下文中您已经设置

public IQueryable<Ingredient> Ingredients { 
    get { return IngredientBases.OfType<Ingredient>(); } }

那么你只需要

using (var context = new MyEntities())
{
    var result = context.Ingredients.Where(i => i.ingredientId = 1);
} 

SQL 方面,方案 1 和方案 2 的第二个选择将产生几乎相同的计划。但在性能方面,scenario2 会更好,更不用说是 1-1 关系表的正确设计了。

于 2013-10-16T22:16:23.923 回答