我目前正在為我的資料庫創建一個 API,其中包含用戶和站點。它們是多對多的關系。當我執行我的“Get”函式時,我希望它是最通用的:它可以有亂數量的引數,甚至是一個“order by”引數。其中一個引數當然是用戶的站點,它是一個長 [] 的 ID。我希望我的陣列中的所有 id 都對應于我的用戶中站點的 id。
例如:List[1,3] => 如果我的用戶有站點 1,2,3 是可以的,但如果他有 1,2,4 就不行。
public async Task<ActionResult<IEnumerable<User>>> GetUser(IEnumerable <long> idSites){
...
resultUsers = DBContext.Users.Where(x => (idSites.Count() > 0)
? (x.Sites.Count() > 0)
? idSites.All(id => x.Sites.All(site => site.Id == id))
: false
: true).ToList();
...
}
為清楚起見,我只將此引數放在 where() 中,但通常我所有的引數都在 where() 中。第一個三元運算式是檢查是否要過濾此引數。第二個是避免一個空的站點串列,當它不是時算作“ok”(我不知道它為什么起作用,但無論如何)。
第一個 .all() 從來沒有給我任何問題。在我看來,無論我是放 all() 還是 any(),第二個都會崩潰。
我要提出錯誤,但我知道它無濟于事。錯誤說我無法將我的行分配給我的串列,因為它錯過了“ToList()”函式。這是因為它在 lambda 運算式中崩潰并且永遠不會到達“toList()”(在我看來)。
編輯:當我放置“AsEnumerable”時,錯誤被洗掉,但我回傳的串列始終為空(當我不過濾該引數時,它已滿)。更重要的是,當我使用這個標簽時,我不能使用 .include() 函式,我用它來獲取站點的值。
它是:
System.InvalidOperationException: The LINQ expression 'DbSet<User>()
.Where(u => DbSet<Dictionary<string, object>>("SiteUser")
.Where(s => EF.Property<Nullable<long>>(u, "Id") != null && object.Equals(
objA: (object)EF.Property<Nullable<long>>(u, "Id"),
objB: (object)EF.Property<Nullable<long>>(s, "UsersId")))
.Join(
inner: DbSet<Site>(),
outerKeySelector: s => EF.Property<Nullable<long>>(s, "SitesId"),
innerKeySelector: s0 => EF.Property<Nullable<long>>(s0, "Id"),
resultSelector: (s, s0) => new TransparentIdentifier<Dictionary<string, object>, Site>(
Outer = s,
Inner = s0
))
.Count() > 0 ? __complexUserParameters_idSites_0
.All(id => DbSet<Dictionary<string, object>>("SiteUser")
.Where(s1 => EF.Property<Nullable<long>>(u, "Id") != null && object.Equals(
objA: (object)EF.Property<Nullable<long>>(u, "Id"),
objB: (object)EF.Property<Nullable<long>>(s1, "UsersId")))
.Join(
inner: DbSet<Site>(),
outerKeySelector: s1 => EF.Property<Nullable<long>>(s1, "SitesId"),
innerKeySelector: s2 => EF.Property<Nullable<long>>(s2, "Id"),
resultSelector: (s1, s2) => new TransparentIdentifier<Dictionary<string, object>, Site>(
Outer = s1,
Inner = s2
))
.All(ti0 => ti0.Inner.Id == id) == True) : False)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
如果您需要更多資訊來幫助我,請告訴我。非常感謝。
uj5u.com熱心網友回復:
也許你可以檢查Intersect()(在 int-s 上應該沒問題)?
public async Task<ActionResult<IEnumerable<User>>> GetUser(IEnumerable <long> idSites){
if (idSites == null || !idSites.Any())
{
resultUsers = DBContext.Users.Tolist(); //Why checking the Count of the input parameter on every User?
}
else
{
resultUsers = DBContext.Users.Where(x => x.Sites.Count() > 0 ?
idSites.Intersect( x.Sites).Count() == idSites.Count() :
false)
.ToList();
}
...
}
uj5u.com熱心網友回復:
嘗試使用 Count 而不是 All。它應該作業:
var query = context.Users.AsQueryable();
if (sites?.Count > 0)
{
query = query.Where(x => x.Sites.Count(s => sites.Contains(s.Id)) == sites.Count);
}
return await query.ToArrayAsync(cancellationToken);
HttpContext.RequestAborted可以用作cancellationToken. 當然可以加.Include(x => x.Sites)。
如果sites變數是陣列,則Count必須在 上更改Length。
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/323858.html
上一篇:如何查詢/轉換資料為所需格式
下一篇:Linq中是/否列中是的百分比
