Asp.net 实体框架从具有不同表关系主键/外键场景的两个表中进行选择

Asp.net 实体框架从具有不同表关系主键/外键场景的两个表中进行选择,asp.net,entity-framework,tsql,foreign-keys,primary-key,Asp.net,Entity Framework,Tsql,Foreign Keys,Primary Key,我有两个示例表: 情景1 表1-成分 ingredientId(PK, int, not null) userId(FK, int, not null) timestamp(datetime, not null) ingredientId(PK, int, not null) userId(FK, int, not null) timestamp(datetime, not null) ingredientId(PK, FK, int, not null) //WITHOUT PRIMARY

我有两个示例表:

情景1

表1-成分

ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
ingredientId(PK, FK, int, not null) //WITHOUT PRIMARY (ingredientAdditionalInformationId) AUTO INCREMENT KEY)
isApproved(bit, not null)
unitsConverted(bit, 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();
  }
}
或者选择with join(我知道您可以使用方法语法进行连接,但我可以更快地使用查询方法编写连接)

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

情景2

表1-成分

ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
ingredientId(PK, FK, int, not null) //WITHOUT PRIMARY (ingredientAdditionalInformationId) AUTO INCREMENT KEY)
isApproved(bit, not null)
unitsConverted(bit, not null)
表2-成分

ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
ingredientId(PK, int, not null)
userId(FK, int, not null)
timestamp(datetime, not null)
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
       });
} 

我想知道哪种表格设计更适合优化选择(场景1或场景2),如果我知道每个成分只有一个条目,并且这是使用实体框架的正确方法,那么如果我真的需要在RedentialAdditionalInformation中使用auto increment key?

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

然后,您可以在实体框架模型中将该属性设置为单个导航属性,并简化EF查询,如下所示。如果您在模型中启用了导航属性的延迟加载,那么如果您是

var result = from i in context.Ingredient.Include("IngredientAdditionalInformation") select i;
然后按如下方式访问属性:

i.IngredientAdditionalInformation.isApproved

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

场景2更好,因为您说两个表之间存在一对一的关系。
您应该探索的另一个选项是使用表每类型继承。在这种情况下,您不需要使用Include或join来指定即时加载

假设您的table1=IngCreditBase,table2=Components,并且在您的上下文中设置了

public IQueryable<Ingredient> Ingredients { 
    get { return IngredientBases.OfType<Ingredient>(); } }
SQL方面,第二次选择scenario1和scenario2将生成几乎相等的计划。但就性能而言,scenario2会更好,更不用说它是1-1关系表的正确设计了