美好的一天,ASP.NET,实体框架等的超级新手。非常精通直线编程,所以我首先要在新方法陷入其中之前尝试忘记旧方法。
我正在开发一个应用程序,它将跟踪FLEET项目(父项)及其所有FLEETEVENT项目(子项)。这两个是通过FleetId字段链接的。
我可以使用:Fleet fleet = db.Fleets.Find(id);
并返回与id变量及其所有子元素匹配的父记录。
我要做的是仅返回子元素FLEETEVENT.STATUS == True
我尝试过使用LINQ表达式和DataLoadOptions.AssosiateWith,但是我得到了所有使用AssociateWith和转换错误的记录,试图使用LINQ表达式。
我认为这样做不应该太难,但我仍然坚持旧的思维方式。
代码snipets如下:
连接器型号:
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语法是否正确,返回了我预期的结果。但是当我在代码中使用它时,我在Fleet fleet代码行中得到了转换错误。
非常感谢能指出正确方向的任何信息。
答案 0 :(得分:3)
首先,在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
如果您想要返回所有拥有Status = 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
答案 1 :(得分:0)
你的问题是Fleet是一个类,而不是List&lt;&gt;()。所以你在调用ToList()时会失败。 同样选择f,fe不是舰队制造的。 :)要选择一个类,你会特别注意这个:
select new MyClass()
{
MyField = f.Field,
MyThingy = fe.thingy
}
您可能想做的事情是这样的:
Fleet fleet = new Fleet()
{
FleetId = results.FleetId,
FleetEventDate = results.FleetEventDate,
...
}
最难的部分是填充对象内的列表。但是你可以枚举fe实例并将每个实例添加到FleetEvents列表中。