关系上的 EF4 条件映射

发布于 2024-10-12 14:41:37 字数 702 浏览 6 评论 0原文

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

例如,我有一个一对多关系,其中商店可以有许多库存记录。商店可以被标记为“IsActive”,属于它的库存记录也可以被标记为“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 字段?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

楠木可依 2024-10-19 14:41:37

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

例子:

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

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
        );
    }   
}
悲喜皆因你 2024-10-19 14:41:37

虽然其他答案可能对某些人有用,但我们决定将 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>

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>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文