使用Entity Framework检查层次结构中的对象是否存在

3
我有一个包含一列外键,该外键与同一表中的主键相关联的Entity Framework类如下所示:
[Table("Items")]
public class Item
{
    [Key]
    public long ItemID { get; set; }

    public string ItemName { get; set; }

    public long? ItemParentID { get; set; }

    [ForeignKey("ItemParentID")]
    public virtual Item Parent { get; set; }

    public virtual ICollection<Item> Children { get; set; }
}

上述映射很棒,我能够通过传递ItemParentID并选择Items来获得Children属性中的所有子项,直到第n级。
在我的业务逻辑中,我有ParentItemID和ChildItemID,并且我必须检查是否在ParentItemID的Children项层次结构中的任何位置存在ChildItemID,它可以存在于ParentItems -> Children及其Children及其Children等中。
我尝试了以下lambda表达式,但仅适用于两个级别的子项:
ParentItem.Children.Contains(context.Items.Where(x => x.ItemID == ChildItem).FirstOrDefault())

我该如何编写简单的LINQ或Lambda语句来返回一个布尔值,以实现这一目标?

你需要递归地遍历所有子节点。我通常会创建一个静态的帮助方法来执行查询,而不是使用LINQ。public Boolean GetChild(Item i){....} - jdweng
@jdweng 是的,那是一种方法,但我希望能在 Entity Framework 内部找到解决方案,因为它已经能够获取所有子项到第 n 级,而不需要编写任何复杂的递归 LINQ 语句。 - seadrag0n
为什么人们认为递归方法很复杂? - jdweng
2个回答

0
我已经编写了以下递归方法来解决这个问题:
public bool CheckIfChildItemExists(ICollection<Item> childItems, long childItemId)
{
    var isChildExisting = false;
    foreach (Item item in childItems)
    {
        if (item.Children.Contains(context.Items.Where(x => x.ItemID == childItemId && x.IsActive).FirstOrDefault()))
        {
            isChildExisting = true;
            return isChildExisting;
        }
        else
        {
            return CheckIfItemChildExists(item.Children, childItemId);
        }
    }
    return isChildExisting;
}

然后像这样调用它:

bool isAccessible = CheckIfChildItemExists(ParentItem.Children, childItemId);

0

最佳实现方式

无论您的对象是什么,以及针对数据库中哪个表格,您唯一需要拥有的就是对象中的主键。

C# 代码

var dbValue = EntityObject.Entry(obj).GetDatabaseValues();
if (dbValue != null)
{
   exist
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接