筛选实体框架上下文以仅返回某些子元素
本文关键字:元素 返回 实体 框架 上下文 筛选 | 更新日期: 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列表中。