[英]Reference to junction table throws ArgumentNullException 'Value cannot be null'
我正在嘗試通過配方的聯結表獲取配料。
_context.RecipeIngredients
.Include(rI => rI.Recipe)
.ThenInclude(r => r.RecipeIngredients)
.Where(rI => ingredients.Contains(rI.IngredientId))
.GroupBy(rI => rI.Recipe)
.Select(g => new
{
Recipe = g.Key,
MatchingIngredients = (double)g.Count() / (double)g.Key.RecipeIngredients.Count(),
g.Key.ComplexityTag,
g.Key.TypeTag,
g.Key.RecipeIngredients,
})
.OrderByDescending(r => r.MatchingIngredients)
.Take(MaxAmountBestRecipes)
.AsEnumerable()
.Select(a => new RecipeDTO()
{
Title = a.Recipe.Title,
Steps = a.Recipe.Steps,
ComplexityTag = a.ComplexityTag?.Complexity,
TypeTag = a.TypeTag?.Type,
IngredientAmount = a.RecipeIngredients?.ToDictionary(rI => rI.Ingredient.Name, rI => rI.Quantity),
})
.ToList();
我發現它是由g.Key.RecipeIngredients引起的,但是我找不到任何解決方法來解決此問題。 我嘗試了eagar加載(如您所見)和延遲加載,兩者均無效。 我希望在linq中對db的一個查詢中有解決方案。 此外,更新后,它是否會像上一行一樣工作:
IngredientAmount = a.RecipeIngredients?.ToDictionary(rI => rI.Ingredient.Name, rI => rI.Quantity)
編輯我划分了linq查詢,在這里您有拋出ArgumentNullException的那條語句:
var tmp = _context.RecipeIngredients
.Where(rI => ingredients.Contains(rI.IngredientId))
.GroupBy(rI => rI.Recipe)
.Select(g => new
{
Recipe = g.Key,
MatchingIngredients = (double)g.Count() / (double)g.Key.RecipeIngredients.Count(),
g.Key.ComplexityTag,
g.Key.TypeTag,
g.Key.RecipeIngredients
})
.ToList();
當您更改查詢的形狀時(例如,當您查詢RecipeIngredient
但投影到另一種類型時, Include
不起作用)。
我認為NULL唯一的問題是創建字典時的鍵選擇器。 由於Include
不會為您做任何事情,因此ri.Ingredient
將始終為NULL。 在原始投影中包含Ingredient
(並刪除Include
因為它沒有用):
_context.RecipeIngredients
.Where( rI => ingredients.Contains( rI.IngredientId ) )
.GroupBy( rI => rI.Recipe )
.Select( g => new
{
Recipe = g.Key,
MatchingIngredientCount = (double)g.Count() / (double)g.Key.RecipeIngredients.Count(),
g.Key.ComplexityTag,
g.Key.TypeTag,
g.Key.RecipeIngredients,
// this eager-loads the `Ingredient` entities
// EF will automatically wire them up to the `RecipeIngredient` entities
// if tracking is enabled
Ingredients = g.Key.RecipeIngredients.Select( ri => ri.Ingredient ),
} )
.OrderByDescending(r => r.MatchingIngredients)
.Take(MaxAmountBestRecipes)
.ToArray()
.Select( a = new ...
{
...
IngredientAmount = a.RecipeIngredients.ToDictionary(
ri => ri.Ingredient.Name, // ri.Ingredient should now not be NULL
ri => ri.Quantity )
} );
編輯:如果您的結果中不需要整個RecipeIngredient
或Recipe
實體,則只需在原始名稱中使用RecipeIngredient
s在第一個投影中投影所需的對象即可:
IngredientNamesAndQuantity = g.Key.RecipeIngredients.Select( ri => new
{
ri.Quantity,
ri.Ingredient.Name,
}
然后使用該投影來構建字典:
IngredientAmount = a.IngredientNamesAndQuantity.ToDictionary(
at => at.Name,
at => at.Quantity )
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.