entity-framework - 在 Entity Framework 中查询 DbContext.Set(TypeVariable)

标签 entity-framework

我正在重构一个应用程序以反转某些依赖关系。部分原代码使用DbContext.Set<MyEntityType>()获取要查询的集合。

通过反转,使用 DbContext.Set<MyEntityType>() 的代码不再明确知道 MyEntityType ,所以现在我正在使用 DbContext.Set(TypeVariable)相反。

重构工作的范围是返回正确的 DbSet。

但是,类型DbContext.Set(TypeVariable).LocalIList (包含类型未知)其中 DbContext.Set<MyEntityType>().Local 的类型是ObservableCollection<MyEntityType> 。这意味着现在不可能针对 DbSet 执行 Linq。

我能够实现的最佳解决方法是转换为 MyEntityType 和其他实体类型实现的接口(interface)(为了清楚起见,省略了一些代码)

var set = Context.Set(targetType);
var entity = set.Local.OfType<IActionTarget>()
    .FirstOrDefault(l => l.Id == key.Id && l.EffectiveDate == key.EffectiveDate);
var querables = set as IQueryable<IActionTarget>;
entity = querables.FirstOrDefault(e => e.Id == key.Id && e.EffectiveDate == key.EffectiveDate);

那么,有两个问题:

为什么不DbContext.Set(TypeVariable)返回强类型集?

有没有更好的方法来进行依赖倒置?

根据要求提供一些进一步的详细信息

这都是关于依赖关系的。该模型包含 POCO 类,这些类通过 EF Code First 以典型方式(但通过存储库)进行持久化。 ActionEvaluator 获取一些传入数据,并通过存储库方法确定需要发生哪些操作 - 因此针对 DbSet 进行查询。

在原始代码中,只有一种类型的传入数据(特定格式的 CSV),并且 ActionEvaluator 对此数据具有紧密依赖性,并且知道哪些 POCO 类适用于哪些 CSV 记录。

现在,我们想要扩展以使用不同的 CSV 格式和 Web API 消息。为此,我们需要反转依赖关系,以便 DataSource 告诉 ActionEvaluator 其记录适用于哪些 POCO 类。这是通过类型变量完成的。

因此,ActionEvaluator 不能再使用泛型类型参数,但它可以将类型变量传递给存储库,存储库使用它来查找正确的 DbSet。

问题在于查找 DbSet 的两种方法之间的差异 - DbContext.Set<AnEntity>()DbContext.Set(TypeVariable) .

我想我要求对 EF 进行增强,以使这两个版本的返回值在功能上等效,但这可能是不可能的,因为第二个版本的类型是在运行时确定的。

这是所要求的完整方法代码:

    private IActionTarget DbContextGetEntity(Type targetType, IActionTarget key)
    {
        var set = Context.Set(targetType);
        if (set == null)
        {
            throw new Exception("Unable to find DbSet for type '{0}'".F(targetType.Name));
        }

        // Look in the local cache first
        var entity = set.Local.OfType<IActionTarget>()
            .FirstOrDefault(l => l.Id == key.Id && l.EffectiveDate == key.EffectiveDate);

        if (entity == null)
        {
            // If not found locally, hit the database
            var querables = set as IQueryable<IActionTarget>;
            if (querables != null)
            {
                entity = querables.FirstOrDefault(e => e.Id == key.Id && e.EffectiveDate == key.EffectiveDate);
            }
        }
        return entity;
    }

理想情况下,我想替换

var entity = set.Local.OfType<IActionTarget>()
    .FirstOrDefault(l => l.Id == key.Id && l.EffectiveDate == key.EffectiveDate);

var entity = set.Local.OfType(targetType)
    .FirstOrDefault(l => l.Id == key.Id && l.EffectiveDate == key.EffectiveDate);

最佳答案

我还没有编译它,所以请原谅任何格式问题 - 你可以使用动态类型来实现同样的事情吗?

private IActionTarget DbContextGetEntity(Type targetType, IActionTarget key)
{
    dynamic instance = Activator.CreateInstance(targetType);
    return DbContextGetEntity(instance, key);
}

private IActionTarget DbContextGetEntity<T>(T instance, IActionTarget key)
    where T : class, IActionTarget
{
    var set = Context.Set<T>(targetType);
    if (set == null)
    {
        throw new Exception();
    }

    // Look in the local cache first
    var entity = set.Local
        .FirstOrDefault(l => l.Id == key.Id && l.EffectiveDate == key.EffectiveDate);

    if (entity == null)
    {
        // If not found locally, hit the database
        entity = set
            .FirstOrDefault(e => e.Id == key.Id && e.EffectiveDate == key.EffectiveDate);
    }
    return entity;
}

关于entity-framework - 在 Entity Framework 中查询 DbContext.Set(TypeVariable),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15481685/

相关文章:

c# - 尝试弄清楚 Entity Framework 中的查询何时执行

c# - 无法访问转换查询中的表(从纯 SQL 到 LINQ)

c# - 在 Entity Framework 中,我有一个 id (int) 用于收集其他类的 id。如何将它从类转换为id?

c# - Entity Framework : C# Winforms bindingsource delete on datagridview, 但仅将 isDeleted 字段标记为真(不删除)

c# - Entity Framework 代码优先 - 创建表并将现有表中的数据插入新创建的表中,

entity-framework - 映射时转换值

c# - 查询变量中的 EF 双斜杠参数未给出任何结果

c# - 可以使用 EF 通过单个查询来查询我的案例吗? (实体的条件和嵌套实体的条件)

asp.net-mvc - 无法检索 'MyService.Entities.Email' 的元数据。 'System.Data.Entity.Internal.AppConfig' 的类型初始值设定项引发异常

php - Symfony2/学说 : how to add more of the same entity in the same collection?