第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機(jī)立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么在通過泛型方法創(chuàng)建時,Select 后的 Linq“where”表達(dá)式會在本地求值?

為什么在通過泛型方法創(chuàng)建時,Select 后的 Linq“where”表達(dá)式會在本地求值?

C#
慕尼黑8549860 2023-08-13 15:43:48
我正在使用泛型實(shí)現(xiàn)規(guī)范模式,并嘗試動態(tài)地將標(biāo)準(zhǔn)應(yīng)用于映射實(shí)體的投影簡單(未映射)版本。一般來說,它工作得很好,但是一旦我在表達(dá)式之后添加Select并應(yīng)用,Linq 就會在本地計(jì)算表達(dá)式Where。如果我將其構(gòu)建為局部變量并傳遞給相同的Where.這是簡化的相關(guān)代碼片段:public interface ISomeable{    string Some { get; set; }}public static Expression<Func<T, bool>> GetCriteria<T>() where T : class, ISomeable    {  return e => (e.Some == "Hello"); }...Expression<Func<MySimpleEntity, bool>> someCriteria = e => (e.Some == "Hello");Expression<Func<MySimpleEntity, bool>> someCriteria2 = GetCriteria<MySimpleEntity>();var query = db.Entities       .Select(s => new MySimpleEntity { Id = s.Id, Some = s.Some });// if this Select is removed and MySimpleEntity in both expressions replaced with MyFullEntity, // the issue disappears// this succeedsvar filteredQueryResults = query.Where(someCriteria).ToList();// at this point, someCriteria2 is set to the same e => (e.Some == "Hello");// this fails: why is it evaluated locally and not in SQL? <-----filteredQueryResults = query.Where(someCriteria2).ToList();// results in a warning:                /*                 * 'Microsoft.EntityFrameworkCore.Query.QueryClientEvaluationWarning:                  * The LINQ expression 'where (new MySimpleEntity() {Id = [s].Id, Some = [s].Some}.Some == "Hello")'                  * could not be translated and will be evaluated locally.'.                  */如何讓它生成正確的 SQL 而不是本地評估someCriteria2?我懷疑我需要某種類型的選角,但不確定在哪里。兩者在調(diào)試器中看起來完全相同,所以我不知道為什么 Linq 會以不同的方式對待它們someCriteria。someCriteria2我創(chuàng)建了一個最小的 .Net Core Console 應(yīng)用程序來重現(xiàn)該案例。完整的要點(diǎn)在這里:https://gist.github.com/progmars/eeec32a533dbd2e1f85e551db1bc53f8NuGet 依賴項(xiàng): Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.6" Microsoft.Extensions.Logging" Version="2.2.0" Microsoft.Extensions.Logging.Console" Version="2.2.0"一些解釋:這與同一個查詢執(zhí)行兩次這一事實(shí)無關(guān)。如果我注釋掉第一個,query.Where(someCriteria).ToList()第二個調(diào)用someCriteria2仍然無法生成有效的 SQL。但是,如果我用第二個查詢替換someCriteria2為someCriteria并讓它運(yùn)行,我會在控制臺中得到兩個完全有效的 SQL 查詢。因此,這一切都與泛型someCriteria2和Select投影有關(guān) - 由于某種原因,Linq 不會以相同的方式對待這兩個變量,即使編譯器(和調(diào)試器監(jiān)視)認(rèn)為它們是相同的確切類型。
查看完整描述

2 回答

?
慕姐8265434

TA貢獻(xiàn)1813條經(jīng)驗(yàn) 獲得超2個贊

問題類似于無法轉(zhuǎn)換基本屬性的 LINQ 表達(dá)式和如何在 EF Core 表達(dá)式中使用繼承的屬性?,但在這種情況下, 和DeclaringTypeReflectedType指向MemberInfo接口ISomeable而不是實(shí)際的類。

這又在某種程度上讓場景中的 EF Core 感到困惑Select。我檢查了最新的 EF Core 3.0 預(yù)覽版,它也不起作用。您可以考慮將其發(fā)布到他們的問題跟蹤器。

到目前為止,我可以提供的唯一解決方法是使用自定義后處理表達(dá)式ExpressionVisitor并將成員訪問器綁定到實(shí)際的類。像這樣的東西:

public static partial class ExpressionUtils

{

? ? public static Expression<T> FixMemberAccess<T>(this Expression<T> source)

? ? {

? ? ? ? var body = new MemberAccessFixer().Visit(source.Body);

? ? ? ? if (body == source.Body) return source;

? ? ? ? return source.Update(body, source.Parameters);

? ? }


? ? class MemberAccessFixer : ExpressionVisitor

? ? {

? ? ? ? protected override Expression VisitMember(MemberExpression node)

? ? ? ? {

? ? ? ? ? ? if (node.Expression != null && node.Expression.Type != node.Member.DeclaringType)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? var member = node.Expression.Type.GetMember(node.Member.Name).Single();

? ? ? ? ? ? ? ? if (member.ReflectedType != member.DeclaringType)

? ? ? ? ? ? ? ? ? ? member = member.DeclaringType.GetMember(member.Name).Single();

? ? ? ? ? ? ? ? return Expression.MakeMemberAccess(node.Expression, member);

? ? ? ? ? ? }

? ? ? ? ? ? return base.VisitMember(node);

? ? ? ? }

? ? }

}

現(xiàn)在


var someCriteria2 = GetCriteria<MySimpleEntity>().FixMemberAccess();

將生成與工作編譯時表達(dá)式完全相同的表達(dá)式someCriteria,并且沒有客戶端評估。


注意:您仍然需要約束class,以避免上一個問題中的轉(zhuǎn)換問題并使此解決方法發(fā)揮作用。


查看完整回答
反對 回復(fù) 2023-08-13
?
慕婉清6462132

TA貢獻(xiàn)1804條經(jīng)驗(yàn) 獲得超2個贊

我認(rèn)為你的代碼的問題是

GetCriteria<MySimpleEntity>();

linq無法直接翻譯sql或沒有直接翻譯。如果你想使用它。執(zhí)行ToList()然后添加.Where(someCriteria2).ToList();. 在觀察者中,它認(rèn)為/評估它是相同的。但在查詢本身中,生成 sql 似乎并不是這樣工作的。

我還經(jīng)歷過,在我的DateTime擴(kuò)展方法中,即使將其轉(zhuǎn)換為string我的擴(kuò)展Where方法,我也必須在linq查詢之外執(zhí)行它并添加它

var dateUtc = DateTime.UtcNow.ExtensionMethod();

...Where(x => x.Date >= dateUtc)

或者我在我的和/或FirstorDefault, First, ToList()之前先執(zhí)行selectwhere


查看完整回答
反對 回復(fù) 2023-08-13
  • 2 回答
  • 0 關(guān)注
  • 130 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號