从查询初始化 DbSet?

Initialize DbSet from query?

我正在尝试弄清楚如何使我的 DbSet 初始化来自自定义查询。

解释:

我的 DbSet 将是只读的。

假设我的数据库中有 3 个表。我写了一个 SQL 查询,对 3 个表进行复杂的选择。现在想用Entity Framework对查询结果进行查询

我认为这可以通过创建这样的东西来实现:

class MyCustomContext : DbContext
{
    public MyCustomContext(string connectionString) 
        : base(connectionString)
    {

    }

    public DbSet<MyQueryResultRow> ResultsRows { get; set; }
}

但我不知道如何对 DbContext 说 "Hey, for retrieving the rows of that DbSet, use that sql query!"。

注意:我不能也不想修改数据库(例如,我不能创建 sql 视图)。

有什么想法吗?

您可以像往常一样创建 dbContext,然后将 SqlQuery 用于 'non entity' 类型。

例如:

using (var context = new myDbContext()) 
{ 
    var things = context.Database.SqlQuery<myType>( 
                       "SELECT things FROM dbo.myTables").ToList(); 
}

关键是使用 context.Database 然后你可以访问所有表(当然你的 SQL 帐户也可以访问!),你可以定义你的 'myType' 映射您选择的列。

创建一个 class 代表 1 到 1 将由 SQL 返回的内容。

这包括数据类型。

public class CustomClass
{
    public int Id {get; set;}
    public string Name {get; set;}
    ....
}

//you  can pass in variables to this method...
public List<CustomClass> GetCustomeClass()
{
    //here you just need to ensure what you select matches the class(CustomClass).
    string query = "Select * from Table_XYS";

    List<CustomClass> res = context.Database.SqlQuery<CustomClass>(query).ToList();

    return res;

}

假设 Table_XYS 有两个字段,Id(int) 和 Name(nvarchar) 那么这将按原样工作。

这里的要点是 SQL 查询可以包括连接或分组依据,或者任何你想要的,只要自定义 Class 和最终的 select 来自SQL 具有相同的 prop/fields.. 包括类型。然后它会为你绑定数据。

也许您可以尝试添加另一层,例如存储库层:

public class MyCustomRepository
{
    private readonly MyCustomContext _context;
    public MyCustomRepository(MyCustomContext context)
    {
        _context = context;
    }

    public IEnumerable<MyQueryResultRow> GetResultRows()
    {
        return _context.ResultsRows.Where(r => r.Id > 10); // Here you can add some restrictions
    }
}

返回 IEnumerable 将不会执行查询。只有在执行 .ToList() 方法后,查询才会在数据库中执行,因此您可以轻松添加更多子句:

var myExtendedQueryResults = repository
    .GetResultRows()
    .Skip(5)
    .OrderBy(r => r.Name)
    .Take(10)
    .ToList();