我有一个父实体,具有子实体的导航属性。只要子实体中存在关联记录,父实体就不能被删除。子实体可以包含数十万条记录。
我想知道在实体框架中最有效的做法是什么:
var parentRecord = _context.Where(x => x.Id == request.Id)
.Include(x => x.ChildTable)
.FirstOrDefault();
// check if parentRecord exists
if (parentRecord.ChildTable.Any()) {
// cannot remove
}
Run Code Online (Sandbox Code Playgroud)
或者
var parentRecord = _context.Where(x => x.Id == request.Id)
.Select(x => new {
ParentRecord = x,
HasChildRecords = x.ChildTable.Any()
})
.FirstOrDefault();
// check if parentRecord exists
if (parentRecord.HasChildRecords) {
// cannot remove
}
Run Code Online (Sandbox Code Playgroud)
第一个查询可能包含数千条记录,而第二个查询则不会,但是第二个查询更复杂。
哪种方法最好?
我正在使用Code First方法并具有以下模型:
public class Person
{
public int ID {get; set;}
public string Name {get; set;}
public int CurrentStationID {get; set;}
public virtual Station CurrentStation {get; set;}
public int CurrentTransportationID {get; set;}
public virtual Transportation CurrentTransporation {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
以下代码在我的控制器中:
Models.Person model = myDBContext.Persons
.Include("CurrentStation")
.Include("CurrentTransportation")
.Where(p => p.ID == 1)
.FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)
即使在DB表"人员"中存在具有(1,"Testname",0,0)的行,"model"也将为NULL .
以上生成一个SQL语句[...] INNER JOIN stations AS [...] LEFT JOIN transportations [...].对于我的所有模型,它始终为第一个导航属性执行INNER JOIN,无论基础表/类型是什么或我指定它们的顺序,它始终是第一个Include().
我不希望INNER JOIN而是所有的LEFT JOIN,因为"CurrentStation"不需要在数据库中.
为什么EF会这样做?我不明白,但我想明白.我没有在任何属性上指定[Required] - 属性,但它的行为就像我做的那样.
不幸的是,没有[Optional] -attribute并且通过OnModelCreate-override执行"HasOptional()"对我来说不是一个选项.
预先感谢您的帮助.我对使用Entity Framework 6include()方法时遇到的情况感到有些困惑.据我所知,include方法的作用就像封闭的对象一样,当对象匹配时也是如此.LEFT JOINNULLOUTER JOIN
我将通过发生在我身上的例子,以便你帮我理解发生了什么.
我的表有以下模型:
public class Booking
{
[Key]
public int ID{ get; set; }
public string Description{ get; set; }
public decimal Amount{ get; set; }
public decimal AmoutPaid{ get; set; }
public DateTime? Checkin { get; set; }
public DateTime? Checkout { get; set; }
[ForeignKey("SourceBooking ")]
public int SourceBookingId { get; set; }
public SourceBooking SourceBooking { get; set; }
}
public class SourceBooking
{
[Key]
public int …Run Code Online (Sandbox Code Playgroud)