【问题标题】:Searching data from multiple tables using Entity framework, Lambda Expressions and Repositorys pattern使用实体框架、Lambda 表达式和存储库模式从多个表中搜索数据
【发布时间】:2018-12-27 11:49:16
【问题描述】:

我有 InfoAppointment 类,并且该类的表中有 Boat 类的外键 Boat_Id。我想显示包含特定船的 InfoApontamento 类的所有记录。我将如何使用 infoAppointment 表中的船类的外键来查找特定的船,使用 lambda 表达式和存储库?它是一对多的关系

public  class InfoAppointment : Entity
{      
    public string Status { get; set; }

    public string Code{ get; set; }

    public string Observation{ get; set; }

    public virtual Boat Boat { get; set; }
}

public class Boat : Entity
{
    public Guid BoatId { get; set; }
    public virtual InfoAppointment  InfoAppointment { get; set; }
} 

我的示例存储库

public virtual IEnumerable<TEntity> Search(Expression<Func<TEntity, bool>> predicate)
{
    return Dbset.Where(predicate);
}

public class InfoAppointment Repository : Repository<InfoAppointment >, IInfoAppointmentRepository
{
    public InfoAppointmentRepository(RveContext rveContext) : base(rveContext)
    {
    }

    public InfoAppointment GetBoatByName(string boatName)
    {
        // HOW TO GET THE BOATS USING THE FK
    }

    public InfoAppointment GetByCode(string code)
    {
        return Search(c => c.active && !c.excluded && c.Code== code).FirstOrDefault();
    }
}

【问题讨论】:

  • name 参数是什么?它应该是InfoAppointment 还是Boat 的属性? (我在任何课程中都没有看到这样的属性)
  • @Miamy 该参数来自下拉列表。 This dropdown will have a list of boats, when selecting one, this method receives that name and would look for if that boat is in some registry of the InfoAppointment class.不知道我的想法对不对
  • 所以name 是船名,对吗?
  • @Miamy 是的!我将进行编辑以使其更清晰

标签: c# asp.net-mvc entity-framework lambda repository-pattern


【解决方案1】:

你可以试试:

public InfoAppointment GetByBoatName(string name) // this name is more semantically correct
{
    return Dbset.FirstOrDefault(c => c.Boat != null && c.Boat.Name == name);
}

并且您不需要在FirstOrDefault 之前使用Where - 最后一个也可以接受谓词,因此您可以修改GetByCode 方法(或仅在Search 方法中使用FirstOrDefault)。

编辑:

适用于一艘船有多个约会的情况。 我建议你真的有下一个定义:

public class Boat : Entity
{
  public Guid BoatId { get; set; }
  public virtual List<InfoAppointment> InfoAppointments { get; set; }
} 

返回所选船的所有约会:

public List<InfoAppointment> GetAllByBoatName(string name)
{
  return Boats.First(c => c.Name == name).InfoAppointments.ToList();
}

为所选船返回一个约会:

public InfoAppointment GetOneByBoatName(string name, 
    Expression<Func<TEntity, bool>> predicate)
{
  return Boats.First(c => c.Name == name).InfoAppointments.FirstOrDefault(predicate);
}

【讨论】:

  • 我忘了说,我的班船,有一个 InfoAppointment 的列表。我什至考虑过这个解决方案,但我怀疑它将如何将 InfoAppointment 表中的外键与它通过下拉列表接收到的名称相关联
  • 请检查更新的答案。此外,如果您编辑您的问题以显示真实的类关系以避免让更多读者感到困惑,那会更好。
【解决方案2】:

您可以使用 .Include 语法。

请参考博客:http://foreverframe.net/when-use-include-with-entity-framework/

代码:

var author = context.Boat.Include(a =&gt; a.InfoAppointment).FirstOrDefault(c=&gt; c.Boat != null c.Boat.Name == &lt;&lt;name&gt;&gt;);

【讨论】:

    【解决方案3】:

    我认为问题出在你们的关系上。船类应该有一个 InfoAppointment 列表,而不是单个对象。
    我不明白为什么你有一艘只能预约一次的船。

    但如果还是这样,只需查询(c =&gt; c.Boat?.Name == name),延迟加载将完成剩下的工作。

    编辑: 至于在您的数据库模型中定义外键,请使用[ForeignKey("BoatId")] 注释,如下所述:http://www.entityframeworktutorial.net/code-first/foreignkey-dataannotations-attribute-in-code-first.aspx

    所以你的 InfoAppointment 类应该是这样的:

    public  class InfoAppointment : Entity
    {      
    public string Status { get; set; }
    
    public string Code{ get; set; }
    
    public string Observation{ get; set; }
    
    public int BoatId { get; set; }
    
    [ForeignKey("BoatId")]
    public virtual Boat Boat { get; set; }
    }
    

    【讨论】:

    • 这是我的错误,实际上我的船类有一个 InfoAppointment 列表,我最终与与 InfoAppointment 类相关的其他类混淆了,但具体来说,我的船类可以有几个 InfoAppointment
    • 但是实体框架如何将 InfoAppointment 表中的外键与它通过下拉列表接收到的名称相关联?我还在测试,我开始想到这种类型的解决方案,但我认为缺少一些东西,因为我怀疑 ORM 将如何将该名称与外键相关联
    猜你喜欢
    • 2014-01-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-11
    • 2012-10-22
    • 2014-10-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多