假設有一個簡單的類,比如:
內部 密封 類 Foo
{
public Foo(DateTimeOffset start)
{
開始 = 開始。
}
public DateTimeOffset Start { get; }
}
在核心域中,我們希望有一個單一的 "定義 "來說明 "開始"Foo的含義。因此,我們要做的是在Foo類中添加一個類似于public bool IsStarted => Start < DateTimeOffset.UtcNow的屬性。
然而,Foo也恰好代表了資料庫中的一個 "物體",這意味著我們希望能夠使用Linq-to-Entities(即Entity Framework)來檢索Foo的串列。
(我知道我們不一定會對在核心領域和資料訪問層之間共享類的想法感到滿意,但這與本問題的重點無關。
當只獲取那些 "已經開始 "的Foo時,我們可以這樣做:
var entities = _someDatabaseContext.Foos.Where(foo => foo.Start < DateTimeOffset.UtcNow)。
但是這顯然意味著重復的邏輯,而且 "開始的 Foo "的 "定義 "將不再是單一的了。
我們更希望能夠做到:
var entities = _someDatabaseContext.Foos.Where(foo => foo.IsStarted)。
這一點,不幸的是,并不能用Linq-to-Entities來翻譯,因為它還沒有 "開始 "的概念。
問題是。什么是封裝Foo的 "started "定義的好方法,使其在應用域和查詢資料庫的層面上隨時可用?
uj5u.com熱心網友回復:
定義一個運算式來表示測驗。 將這個運算式與Linq-to-Entities一起使用,使用編譯后的委托來執行。
定義一個運算式來表示測驗。
Expression<Func<Foo, bool>> FooIsStartedPredicateExpression = foo => foo.Start < DateTimeOffset.UtcNow。
Func<Foo, bool> FooIsStartedPredicateDelegate = FooIsStartedPredicateExpression.Compile()。
...
Foo someFooVar = ...。
var isStarted = FooIsStartedPredicateDelegate(someFooVar)。
var foos = _someDatabaseContext.Foos.Where(FooIsStartedPredicateExpression)。
uj5u.com熱心網友回復:
我建議使用LINQKit完成這樣的任務:
builder
.UseSqlServer(connectionString)
.WithExpressionExpanding(); //啟用LINQKit擴展。
定義你的proeprty:
internal sealed class Foo
{
public Foo(DateTimeOffset start)
{
開始 = 開始。
}
public DateTimeOffset Start { get; }
[Expandable(name(IsStartedImpl))]
public bool IsStarted { get; } = Start < DateTimeOffset.UtcNow;
private static Expression<Func<Foo, bool> > IsStartedImpl()
=> foo => foo.Start < DateTimeOffset.UtcNow;
}
然后你可以使用這個屬性作為過濾器:
var entities = _someDatabaseContext.Foos.Where(foo => foo.IsStarted)。
uj5u.com熱心網友回復:
也許可以嘗試把開始的邏輯作為一個謂詞,從IsStarted公共介面中呼叫它,并把它傳遞給Linq代碼?
internal sealed class Foo
{
public Foo(DateTimeOffset start)
{
開始 = 開始。
}
public DateTimeOffset Start { get; }
public bool IsStarted()
{
return _startedPredicate(this)。
}
private readonly Func<Foo, bool> _startedPredicate =
foo => foo.Start < DateTimeOffset.UtcNow;
}
而當使用Linq時
var entities = _someDatabaseContext.Foos.Where(_startedPredicate);/code>
取決于你在哪里訪問資料庫,該謂詞可能需要在Foo之外訪問。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/310069.html
標籤:
