按字符串名称查询

本文关键字:查询 字符串 | 更新日期: 2023-09-27 18:09:33

是否有办法通过实体的字符串名称查询实体框架?目前,我正在通过使用实体框架实现WCF OData服务来实现这一点。我构建URI并针对DbContext执行它(请参阅下面的当前实现)。这适用于简单的实体,但任何具有大量导航属性和数千条记录的复杂实体都会以内存不足异常导致IIS工作进程崩溃。

当前实现:

public static IEnumerable<object> GetList(string entityName)
{
    Uri dataAccessURI = New Uri(string.Format("https://MyServer/Service.svc/{0}", entityName))
    result = DbContext.Execute<object>(dataAccessURI , "GET", true);
    return result;
}

我可以通过实体名称完成保存,那么查询呢?

db.AddObject(entityName, record);
db.SaveChanges();

注意:我不能使用泛型。我希望能够使用像

这样的东西
public static DbSet<TEntity> GetList<TEntity>()

但是我不能,因为应用程序只传递了实体的字符串名称

按字符串名称查询

DbContext可以根据提供的type创建DbSet。并且可以从string创建type。因此,如果你知道实体的名称你应该能够这样做:

public static IEnumerable<object> GetList(string entityName)
{
    Type entityType = Type.GetType(string.format("Namespace.{0}, MyAssembly", entityName);
    DbSet dbSet = DbContext.Set(entityType);
    // DbSet implements IEnumerable, so you will be able to safely cast it like so.
    // Or you can assign it to IEnumerable directly.
    IEnumerable list = dbSet as IEnumerable;
    return list.Cast<object>.ToList();
}

这不是最好的解决方案。但它是有效的。我不知道对性能的影响。

它有一个明显的缺点,你需要知道实体的名称空间。但只要所有实体都在相同的名称空间中,例如DataAccess.ModelsDataAccess.Entitites,它就应该工作。

还要注意,这将查询整个表并获取所有行。这可能是你想要的,也可能不是。您可能还想把DbContext放在某个地方。

您可以在EF中使用以下转换编写自己的查询:

using (var context = new BloggingContext()) 
{ 
    var blogNames = context.Database.SqlQuery<string>( 
                       "SELECT Name FROM dbo.Blogs").ToList(); 
}

但是如果你想生成动态查询,我强烈建议你使用Dapper。它做了类似的事情,但要快得多。你可以在这里阅读更多关于dapper的信息。