在自引用表中对数据进行排序

时间:2012-08-15 15:09:50

标签: entity-framework entity-framework-4 ef-code-first

我有一张桌子可以存放一些产品。

ProductA
ProductB
ProductC

其中一个要求是一个产品可以属于另一个产品

ProductA
ProductD -> ProductA
ProductE -> ProductA
ProductB
ProductF -> ProductB
ProductC

如您所见,属于其他产品的产品必须位于其下方。所有数据必须属于一个列表(没有嵌套集合),因为我只需要在一个网格中显示数据。

如果我引入一个新属性ReferenceProductId,指向另一个产品,那么我解决了“归属”的问题,但我无法找到如何对它们进行排序的方法。 easyiset方式是我可以说ProductA属于ProductA,但如果我没有弄错的话,这是不可能的。此外,当我将一种产品分配给另一种产品时,我不能这样做:

product.ReferenceProductId = anotherProduct.Id

我需要自己分配一个引用,因为我正在使用身份主键,因此对于新记录,Id将为0。

product.ReferenceProduct = anotherProduct;

你的想法在这里?我可以正确地保存数据,但是我无法按上述排序顺序加载它们。

1 个答案:

答案 0 :(得分:2)

您可以创建自定义比较器来订购列表。这只是一个例子,但是它使用比较Id和参考ID,它允许我实现你想要的结果,假设当没有产品参考时referenceId为null。如果通过调用product.Reference.Id来更新FK,您可以更改代码,但为了简单起见,我忽略了这一点。

我的产品类:

    public class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int? ReferenceId { get; set; }
    }

比较器:

public class ProductComparer : IComparer<Product>
{
    public int Compare(Product product, Product other)
    {
        if (product.ReferenceId == null && other.ReferenceId == null)
            return product.Id.CompareTo(other.Id);

        if (product.ReferenceId == null && other.ReferenceId != null)
            return product.Id.CompareTo(other.ReferenceId);

        if (product.ReferenceId != null && other.ReferenceId == null)
            return ((int) product.ReferenceId).CompareTo(other.Id);

        if (product.ReferenceId == other.ReferenceId)
            return product.Id.CompareTo(other.Id);

        return ((int) product.ReferenceId).CompareTo((int) other.ReferenceId);
    }
}

然后你会用这样的东西打电话给你的收藏:

products.OrderBy(p => p, new ProductComparer());