[英]Reference to junction table throws ArgumentNullException 'Value cannot be null'
I'm trying to get Ingredients through junction table for my Recipes. 我正在尝试通过配方的联结表获取配料。
_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();
I discovered it is caused by g.Key.RecipeIngredients, but I can't find any workaround, solution for this problem. 我发现它是由g.Key.RecipeIngredients引起的,但是我找不到任何解决方法来解决此问题。 I tried eagar loading(as you can see), and lazy loading, both didn't work.
我尝试了eagar加载(如您所见)和延迟加载,两者均无效。 I hope there is solution in one query to db in linq.
我希望在linq中对db的一个查询中有解决方案。 Moreover, will it work like in the above line, after update.:
此外,更新后,它是否会像上一行一样工作:
IngredientAmount = a.RecipeIngredients?.ToDictionary(rI => rI.Ingredient.Name, rI => rI.Quantity)
EDIT I have divied linq query and here you have after which statement ArgumentNullException is thrown: 编辑我划分了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();
Include
doesn't work when you change the shape of the query (eg when you're querying for RecipeIngredient
s but are projecting to another type). 当您更改查询的形状时(例如,当您查询
RecipeIngredient
但投影到另一种类型时, Include
不起作用)。
The only place I'm thinking a NULL is a problem is the key selector when creating the dictionary. 我认为NULL唯一的问题是创建字典时的键选择器。 Since
Include
won't do anything for you, ri.Ingredient
will always be NULL. 由于
Include
不会为您做任何事情,因此ri.Ingredient
将始终为NULL。 Include the Ingredient
s in the original projection (and remove the Include
since it's useless): 在原始投影中包含
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 )
} );
Edit: if you don't need the entire RecipeIngredient
or Recipe
entities in your results, just project what you need in the orig name with the RecipeIngredient
s in the first projection: 编辑:如果您的结果中不需要整个
RecipeIngredient
或Recipe
实体,则只需在原始名称中使用RecipeIngredient
s在第一个投影中投影所需的对象即可:
IngredientNamesAndQuantity = g.Key.RecipeIngredients.Select( ri => new
{
ri.Quantity,
ri.Ingredient.Name,
}
Then use that projection to build your dictionary: 然后使用该投影来构建字典:
IngredientAmount = a.IngredientNamesAndQuantity.ToDictionary(
at => at.Name,
at => at.Quantity )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.