我正在使用带有Entity Framework 6.1.3和SQL Server的C#。我有以下实体:
public partial class Contract
{
public Contract()
{
this.Records = new List<Record>();
}
public int Id { get; set; }
public string Name { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public System.DateTime Created { get; set; }
public virtual ICollection<Record> Records { get; set; }
}
public partial class Record
{
public Record()
{
this.Contracts = new List<Contract>();
}
public string Name { get; set; }
public string Description { get; set; }
public DateTime? Published { get; set; }
public int RecordID { get; set; } // Primary key
public int Version { get; set; } // Primary key
public virtual ICollection<Contract> Contracts { get; set; }
}
他们有多对多的关系。合同有很多记录,可以发布或不发布记录。发布记录时,版本会增加。
现在,我想选择所有Contract
合同Record
,其中Version
Published
设置为某个日期的Name
Description
和{{1}设置为特定值。我只对最高Version
的记录感兴趣,该记录也将Published
设置为值。 Published
的具体日期并不有趣。
Pseudo:获取最后发布的记录名称==“bar”的合同。
// Table data for Records (Description left out for sake of formatting)
RecordId | Name | Version | Published
1 | Bar | 1 | 2015-01-01
1 | Foo | 2 | 2015-02-01
1 | Bar | 3 | 2015-03-01
1 | Foo | 4 | 2015-04-01
1 | Bar | 5 | 2015-05-01
1 | Bar | 6 | 2015-06-01
1 | Foo | 7 | 2015-07-01 // I want this one.
1 | Foo | 8 | NULL // not interesting.
我最初尝试过这个:
var result = context.Contracts.Where(
x =>
x.Records.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.FirstOrDefault(r => r.Name == "foo") != null);
但是它实际上只是按版本排序,然后检查是否有任何带有Name == "foo"
的项目,而不是具有最高版本的项目也是已发布的,因此排序实际上不会带来任何内容。所以我试过这个:
var result =
context.Contracts.Where(
x =>
x.Records.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.FirstOrDefault().Name == "foo");
哪个更正确,但现在可能会导致空值异常。我还想检查Description
是否有值,这将创建此查询:
var result =
context.Contracts.Where(
x =>
x.Records.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.FirstOrDefault() != null &&
x.Records.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.FirstOrDefault().Name == "foo" &&
x.Records.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.FirstOrDefault().Description == "some value");
但它看起来效率不高。还有更好的方法吗?
答案 0 :(得分:1)
您可以使用FirstOrDefault
来限制集合,然后使用Take(1)
应用所需的条件,而不是Any
:
var result = context.Contracts
.Where(x => x.Records
.Where(r => r.Published.HasValue)
.OrderByDescending(r => r.Version)
.Take(1)
.Any(r => r.Name == "foo" && r.Description == "some value"));
答案 1 :(得分:0)
您也可以尝试:
.Where(r => r.Published.HasValue &&
r.Name == "foo" &&
r.Description == "some value")
.Max(r => r.Version) != null