筛选实体框架上下文以仅返回某些子元素

本文关键字:元素 返回 实体 框架 上下文 筛选 | 更新日期: 2023-09-27 18:24:21

大家好,ASP.NET、实体框架等的超级新手。我非常精通直线编程,所以我首先必须尝试忘记旧的方法,然后才能理解新的方法

我正在开发一个应用程序,该应用程序将跟踪FLEET项(父项)及其所有FLEETEVENT项(子项)。两者通过FleetId字段链接。

我可以使用:Fleet fleet = db.Fleets.Find(id);,它返回与id变量匹配的父记录及其所有子元素。

我想做的是只返回FLETEVENT.STATUS==True 所在的子元素

我尝试过使用LINQ表达式和DataLoadOptions.AssociateWith,但我得到了所有在尝试使用LINQ表达时出现AssociateWith和转换错误的记录。

我想做这件事应该不会太难,但我还是停留在我以前的思维方式上。

代码狙击手如下:

连接器型号:

public class FleetContext : DbContext
{
    public FleetContext() : base("DefaultConnection")
    {
    }
    public DbSet<Fleet> Fleets { get; set; }
    public DbSet<FleetEvent> FleetEvents { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FleetConfiguration());
        modelBuilder.Configurations.Add(new FleetEventConfiguration());
    }
}

父模型:

public class Fleet : IObjectWithState
{
    public Fleet()
    {
        FleetEvents = new List<FleetEvent>();
        Status = true;
    }
    public System.Guid FleetId { get; set; }
    public string FleetType { get; set; }
    public string FleetNum { get; set; }
    public string FleetMake { get; set; }
    public string FleetModel { get; set; }
    public int FleetYear { get; set; }
    public bool Status { get; set; }
    public byte[] RowVersion { get; set; }
    public ObjectState ObjectState { get; set; }
    public virtual List<FleetEvent> FleetEvents { get; set; }
}

儿童模型:

public class FleetEvent : IObjectWithState
{
    public System.Guid FleetEventId { get; set; }
    public DateTime FleetEventDate { get; set; }
    public string FleetEventType { get; set; }
    public string FleetEventDesc { get; set; }
    public bool Status { get; set; }
    public byte[] RowVersion { get; set; }
    public System.Guid FleetId { get; set; }
    public Fleet Fleet { get; set; }
    public ObjectState ObjectState { get; set; }
}

使用LINQ,这是我正在使用的控制器中的代码:

var result = from f in db.Fleets
                     join fe in db.FleetEvents
                         on f.FleetId equals fe.FleetId
                     where ((f.FleetId == id) && (fe.Status == true))
                     select new { f, fe };
        Fleet fleet = result.ToList();

我已经通过LinqPad返回我期望的结果来验证LINQ语法是正确的。但当我在代码中使用它时,舰队代码行中会出现转换错误。

任何能为我指明正确方向的信息都将不胜感激。

筛选实体框架上下文以仅返回某些子元素

首先,在Entity框架中,您应该学习如何使用导航属性进行查询,并避免不惜任何代价进行联接。

这是样品,

// return all FleetEvents where FleetEvent.Status = true for fleetID = n...
var result = db.FleetEvents
                 .Where(x=> x.Status == true && x.FleetID = id)
                 .Select( x=> new {
                        Fleet = x.Fleet,
                        FleetEvent = x
                     } );
// however result is of anonymous type, so you get Fleet and 
// FleetEvent both as properties of result

如果您想返回所有具有Status=true 的子级的舰队

var fleets = db.Fleets
               .Where( x=> x.FleetID == id && 
                           x.FleetEvents.Any(f=> f.Status == true));
// fleets is now and enumerable with all fleets with atleast 
// one child having Status=true

如果您想返回所有子级状态为true 的所有车队

var fleets = db.Fleets
               .Where( x=> x.FleetID == id )
               .Select( x=> new {
                    Fleet = x,
                    FleetEvents = x.FleetEvents.Where(f=> f.Status == true)
               });
// here you have once again Anonymous type with Fleet and all FleetEvents 
// with Status = true

您的问题是Fleet是一个类,而不是List<>()。因此,在调用ToList()时会失败。同样选择f,fe不是Fleet品牌。:)要选择一个类,你会专门做类似的事情:

select new MyClass()
{
      MyField = f.Field,
      MyThingy = fe.thingy
}

你可能想做的是这样的事情:

Fleet fleet = new Fleet()
{
      FleetId = results.FleetId,
      FleetEventDate = results.FleetEventDate,
      ...
}

最困难的部分将是填充对象内部的列表。但是您可以枚举fe实例,并将每个实例添加到FleetEvents列表中。