【问题标题】:EF DB Context Is Null On Generically Retrieved EntitiesEF DB 上下文在一般检索的实体上为空
【发布时间】:2021-12-22 17:47:10
【问题描述】:

我正在四处寻找一种方法来统一一些数据库的数据访问层,这些数据库具有相同的字段类型但驻留在不同的 EF DB 上下文中。我想出了这样的东西(请忽略字符串插值,这只是一个原型):

public static T FetchEvent<T>(System.Data.Entity.DbContext dbContext, int eventId) where T : class, IEvent
{
    var record = dbContext.Database.SqlQuery<T>($"SELECT * FROM Events WHERE EventId = {eventId}").SingleOrDefault();
    return record;
}

每个数据库都有一个 Events 表,相关的 EF 实体实现 IEvent,其中 IEvent 只是模拟表结构的字段及其数据类型。使用通用 T 参数,在检索记录时由调用代码指定正确的本地 EF 实体类型。

代码运行并返回记录,但是动态代理对象上的 EF 上下文为空,因此您无法对实体进行任何更新。

我的问题:当我以这种方式检索记录时,有没有办法让 EF 上下文保持不变?

【问题讨论】:

  • 警告您的代码为潜在的 sql 注入做好准备
  • 什么版本的ef?
  • @DanielA.White 这是 EF 6
  • @Guru Stron 的回答能解决你的问题吗?
  • @SaeedEsmaeelinejad 是的:]

标签: c# sql entity-framework generics


【解决方案1】:

由于所有事件都具有相同的字段,可以提取到接口并假设具体的 T 映射到相应的上下文,您可以使用 DbContext.Set&lt;T&gt; 方法:

public interface IEvent
{
    public int EventId {get; set;}
    // rest of the props 
}

public static T FetchEvent<T>(System.Data.Entity.DbContext dbContext, int eventId) where T : class, IEvent
{
    var record = dbContext
        .Set<T>()
        .Where(e => e.EventId == eventId)
        .SingleOrDefault();
    return record;
}

【讨论】:

  • 感谢大师,成功了!您是否还写过关于如何调用Set&lt;T&gt;() 以启用更改跟踪的较早回复(因为使用没有它的查询已禁用更改跟踪)?
  • @Snake_Plissken 很乐意提供帮助!不,这是我发布的唯一答案。
  • 同样重要的是:如果底层类是用 VB 编写的,则需要使用原始 SQL 查询方法,否则调用会失败并出现 The specified type member is not supposed by LINQ to entities 错误。我认为这与VB如何实现接口有关,您必须显式处理它们,而C#支持隐式处理。
猜你喜欢
  • 2018-04-12
  • 1970-01-01
  • 2015-09-25
  • 1970-01-01
  • 2014-11-23
  • 2015-09-12
  • 1970-01-01
  • 2011-08-02
  • 1970-01-01
相关资源
最近更新 更多