[英]How can I use Entity Framework to do a common LINQ query on a properties with different names?
Using Entity Framework 4.0, I've defined two simple Entities with generated code that looks like this: 使用Entity Framework 4.0,我使用生成的代码定义了两个简单的实体,如下所示:
public partial class Person : EntityObject
{
public string Name { ... generated code ... }
public DateTime Birthday { ... generated code ... }
}
public partial class Sale : EntityObject
{
public int ProductId { ... generated code ... }
public DateTime DateSold { ... generated code ... }
}
This particular example is contrived, but represents a real problem I'm facing. 这个特定的示例是人为设计的,但是却代表了我面临的一个真正的问题。 Often in my code, I want to restrict Entities to ones that appear in a particular date range.
通常,在我的代码中,我想将实体限制为出现在特定日期范围内的实体。 So I have a lot of instances of:
因此,我有很多实例:
entities.Sales.Where(sale => sale.DateSold > startDate && sale.DateSold < endDate);
entities.People.Where(person => person.Birthday > startDate && person.Birthday < endDate);
is it possible to set up a common method that can handle this? 有可能建立一个通用的方法来解决这个问题吗? Something like
就像是
entities.Sales.WithinRange(startDate, endDate);
would be perfect, and I realize that I could set up an extension method for each and every IQueryable<T>
, but I'd like to flexibility to be able to use the WithinRange() method inside common code. 会很完美,我意识到我可以为每个
IQueryable<T>
设置一个扩展方法,但是我希望能够在通用代码中灵活使用InsideRange()方法。 For example: 例如:
public static IQueryable<T> GetSortedNonNullObjectsInRange<T>(this IQueryable<T> data, DateTime startDate, DateTime endDate) where T : IHasDateDefined
{
return data.Where(entity => entity != null).WhereInRange(startDate, endDate).OrderBy(entity => entity.Date);
}
when I try to use a common interface (like IHasDateDefined), I have the Date property on the interface return the Birthday or DateSold as appropriate, but then Entity Framework throws errors that it can't build an expression. 当我尝试使用公共接口(如IHasDateDefined)时,我在接口上具有Date属性,并根据需要返回Birthday或DateSold,但随后Entity Framework抛出了无法构建表达式的错误。
I think you can achieve what you want with the following: 我认为您可以通过以下方法实现您想要的:
add a static method on your entity-object with the following signature: Expression> CheckWithinRange (DateTime startDate, DateTime endDate) (and yes, in the Person, the T should actually be replaced with 'Person') 在具有以下签名的实体对象上添加静态方法:Expression> CheckWithinRange(DateTime startDate,DateTime endDate)(是的,在Person中,T实际上应替换为“ Person”)
extend your context using a .tt script so that a method is added for each table (eg Person and Sale), which uses the static added methods to add the expression of the entity-object to the request IQueryable. 使用.tt脚本扩展上下文,以便为每个表(例如Person和Sale)添加一个方法,该方法使用静态添加的方法将实体对象的表达式添加到请求IQueryable。 You can also indeed create an extension method to the specific IQueryable<...> types.
您实际上也可以为特定的IQueryable <...>类型创建扩展方法。
Example. 例。
The method added to the Person class: 该方法添加到Person类中:
Expression<Func<Person, bool>> CheckWithinRange (DateTime startDate, DateTime endDate) {
return p => startDate <= p.Birthday && p.Birthday <= endDate;
}
The extension method added to IQueryable 扩展方法已添加到IQueryable
public IQueryable<Person> WithinRange(this IQueryable<Person> data, DateTime startDate, DateTime endDate) {
return data.Where(Person.CheckWithinRange(startDate, endDate));
}
So instead of adding a property to each class which returns the property you want to check, add the logic of the check to each class. 因此,与其在每个类中添加一个返回要检查的属性的属性,不如在每个类中添加检查的逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.