I find myself repeating business-rules too much in my LinqToEntities when querying. That's not good. ;)
在查询时,我发现自己在LinqToEntities中重复了业务规则。这不好。 ;)
Say I have two tables:
说我有两张桌子:
Member
- Id
- Name
MemberShip
- Id
- MemberId (fk to member.Id)
- StartDate
- ExpirationDate
- IsCancelled
MemberId(fk to member.Id)
Now I define a valid membership as:
现在我将有效的成员资格定义为:
- Now is between StartDate and ExpirationDate
- IsCancelled is false
现在介于StartDate和ExpirationDate之间
IsCancelled是假的
So now I would write functions in repositories like...:
所以现在我会在库中写函数,比如...:
- GetActiveMemberships
- GetMembersWithActiveMemberships
- MemberHasActiveMembership
- (etc)
...So in all these functions, that use LinqToEntities, I have code like..:
...所以在使用LinqToEntities的所有这些函数中,我有类似的代码:
...
And membership.IsCancelled = 0 _
And membership.StartDate < Now() _
And membership.ExpirationDate > Now() _
...
What is the best way to avoid repeating this in every single Linq-to-entities query?
Can I separate my definition of a valid membership and apply that in other functions?
在每个Linq-to-entities查询中避免重复此操作的最佳方法是什么?我可以将我对有效会员资格的定义分开并将其应用于其他功能吗?
1 个解决方案
#1
It looks like you're using VB.NET. I apologize for answering with some C# code, but hopefully you can translate.
看起来你正在使用VB.NET。我为回答一些C#代码而道歉,但希望你能翻译。
I can think of a couple ways of tackling this. The first idea is to create a function that returns a predicate of type Func. This allows EF to reverse engineer the predicate into a query. For example:
我可以想到几种方法来解决这个问题。第一个想法是创建一个返回类型为Func的谓词的函数。这允许EF将谓词反向工程为查询。例如:
static Func<MemberShip, bool> IsActiveMember()
{
return m => (
(m.IsCancelled == 0) &&
(m.StartDate < DateTime.Now) &&
(m.ExpirationDate > DateTime.Now));
}
The big drawback to this approach is that you can't use the "comprehension query" syntax (from...where...select). You have to use the LINQ methods directly, as in:
这种方法的一大缺点是你不能使用“理解查询”语法(来自...... where ... select)。您必须直接使用LINQ方法,如:
var context = new AppEntities();
var activeMembers = context.MemberShipSet.Where(IsActiveMember());
Depending on how you need to use it, a better approach might be to create a function or property that returns the set of MemberShip entities pre-filtered to only include the "active" ones. Here is an example of extending the context class created by the EF designer with such a property:
根据您需要使用它的方式,更好的方法可能是创建一个函数或属性,该函数或属性返回预过滤的MemberShip实体集,仅包含“活动”实体。以下是使用此类属性扩展EF设计器创建的上下文类的示例:
partial class AppEntities
{
public IQueryable<MemberShip> ActiveMembers
{
get
{
return
from m in this.MemberShipSet
where (
(m.IsCancelled == 0) &&
(m.StartDate < DateTime.Now) &&
(m.ExpirationDate > DateTime.Now))
select m;
}
}
}
The neat thing about this approach is that you can formulate LINQ queries against ActiveMembers. For example:
这种方法的巧妙之处在于您可以针对ActiveMembers制定LINQ查询。例如:
var lastThirty = DateTime.Now.AddDays(-30);
var context = new AppEntities();
var recentActiveMembers =
from mr in context.ActiveMembers
where (mr.StartDate > lastThirty)
select mr;
#1
It looks like you're using VB.NET. I apologize for answering with some C# code, but hopefully you can translate.
看起来你正在使用VB.NET。我为回答一些C#代码而道歉,但希望你能翻译。
I can think of a couple ways of tackling this. The first idea is to create a function that returns a predicate of type Func. This allows EF to reverse engineer the predicate into a query. For example:
我可以想到几种方法来解决这个问题。第一个想法是创建一个返回类型为Func的谓词的函数。这允许EF将谓词反向工程为查询。例如:
static Func<MemberShip, bool> IsActiveMember()
{
return m => (
(m.IsCancelled == 0) &&
(m.StartDate < DateTime.Now) &&
(m.ExpirationDate > DateTime.Now));
}
The big drawback to this approach is that you can't use the "comprehension query" syntax (from...where...select). You have to use the LINQ methods directly, as in:
这种方法的一大缺点是你不能使用“理解查询”语法(来自...... where ... select)。您必须直接使用LINQ方法,如:
var context = new AppEntities();
var activeMembers = context.MemberShipSet.Where(IsActiveMember());
Depending on how you need to use it, a better approach might be to create a function or property that returns the set of MemberShip entities pre-filtered to only include the "active" ones. Here is an example of extending the context class created by the EF designer with such a property:
根据您需要使用它的方式,更好的方法可能是创建一个函数或属性,该函数或属性返回预过滤的MemberShip实体集,仅包含“活动”实体。以下是使用此类属性扩展EF设计器创建的上下文类的示例:
partial class AppEntities
{
public IQueryable<MemberShip> ActiveMembers
{
get
{
return
from m in this.MemberShipSet
where (
(m.IsCancelled == 0) &&
(m.StartDate < DateTime.Now) &&
(m.ExpirationDate > DateTime.Now))
select m;
}
}
}
The neat thing about this approach is that you can formulate LINQ queries against ActiveMembers. For example:
这种方法的巧妙之处在于您可以针对ActiveMembers制定LINQ查询。例如:
var lastThirty = DateTime.Now.AddDays(-30);
var context = new AppEntities();
var recentActiveMembers =
from mr in context.ActiveMembers
where (mr.StartDate > lastThirty)
select mr;