EF4条件映射关系

时间:2011-01-17 19:56:14

标签: .net-4.0 entity-framework-4

我目前正在使用EF4中的条件映射来过滤掉其IsActive列为false的任何记录。这可以按预期工作,但在导航关系时我遇到了一个问题。

作为一个例子,我有一对多关系,其中商店可以有很多库存记录。商店可以标记为IsActive,属于它的库存记录也可以。直接查询这些表中的记录按预期工作(仅返回活动记录),但我也能够检索关联存储未处于活动状态的库存记录。这允许访问非活动存储,并且无法检测存储是否处于活动状态。

在切换到使用条件映射之前,我们使用类似于以下的查询:

Inventories.Where(i => i.IsActive && i.Store.IsActive && i.Product.IsActive && i.Product.Id == productId);

我希望我们可以简化这个查询:

Inventories.Where(i => i.Product.Id == productId);

这对我不起作用,因为我不再知道Store或Product是否处于活动状态(因为我仍然无法在IsActive上使用条件映射,同时仍然映射该列)。

在利用EF4中的条件映射时,有没有办法复制该查询?我是否被迫离开条件映射并希望所有查询都确保检查所有相关的IsActive字段?

2 个答案:

答案 0 :(得分:1)

您可以编写表达式访问者以将这些属性添加到查询中。

示例:

public abstract class ActiveObject
{
    public bool IsActive { get; set; }

    protected ActiveObject()
    {
        this.IsActive = true;
    }
}

public class Inventory : ActiveObject
{
    public Product Product { get; private set; }

    public Store Store { get; private set; }

    public Inventory()
    {
        this.Store = new Store();
        this.Product = new Product { Id = 10 };
    }
}

public class Product : ActiveObject
{
    public int Id { get; set; }
}

public class Store : ActiveObject
{
    public int Id { get; set; }
}

class Program
{
    static void Main()
    {
        Expression<Func<Inventory, bool>> expression = i => i.Product.Id == 10;
        Expression<Func<Inventory, bool>> expression2 = Rewrite(expression);
    }

    private static Expression<Func<Inventory, bool>> Rewrite(Expression<Func<Inventory, bool>> lambdaExpression)
    {
        var inventory = lambdaExpression.Parameters[0];
        return Expression.Lambda<Func<Inventory, bool>>(
            Expression.AndAlso(
                Expression.AndAlso(
                    Expression.Property(
                        inventory,
                        "IsActive"
                    ),
                    Expression.AndAlso(
                        Expression.Property(
                            Expression.Property(
                                inventory,
                                "Store"
                            ),
                            "IsActive"
                        ),
                        Expression.Property(
                            Expression.Property(
                                inventory,
                                "Product"
                            ),
                            "IsActive"
                        )
                    )
                ),
                lambdaExpression.Body
            ),
            inventory
        );
    }   
}

答案 1 :(得分:0)

虽然另一个答案可能适用于某些人,但我们决定将EF EntitySet映射到视图。视图连接到适当的表并检查其相应的IsActive字段。我们的EDMX的结果部分看起来类似于以下内容:

<EntitySet Name="Inventory" EntityType="Model.Store.Inventory" store:Type="Views" store:Schema="dbo" store:Name="Inventory">
    <DefiningQuery>SELECT 
  [ActiveInventory].[InventoryId] AS [InventoryId],
  {Other columns being selected}
  FROM [dbo].[ActiveInventory] AS [ActiveInventory]</DefiningQuery>
</EntitySet>