开发者

EF4 conditional mapping over a relationship

I'm currently using conditional mappings in EF4 to filter out any records where their IsActive column is false. This works as intended, but I'm running into an issue when navigating relationships.

As an example, I have a one-to-many relationship where a Store can have many Inventory records. A Store can be marked IsActive as can the Inventory records that belong to it. Querying directly for records in those tables works as intended (only active records are returned), but I am also able to retrieve Inventory records where the associated store is not active. This allows the inactive Store to be accessed and gives me no way of detecting whether the store is active.

Prior to switching over to using conditional mapping, we were using queries similar to the following:

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

I was hoping we could simplify that query to this:

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

This doesn't work for me though, as I no longer have any way of开发者_如何学JAVA knowing whether the Store or Product are active (as I can't use conditional mapping on IsActive while still mapping that column).

Is there any way of replicating that query while taking advantage of conditional mapping in EF4? Am I forced to leave conditional mapping out of this and hope that all queries make sure to check all relevant IsActive fields?


You could write an expression visitor to add those properties to your query.

Example:

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
        );
    }   
}


While the other answer may work for some, we decided to map the EF EntitySet to a view instead. The view joins to appropriate tables and checks their appropriate IsActive fields. The resulting portion of our EDMX looks similar to the following:

<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>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜