2015-10-06 73 views
0

我想弄清楚如何使我的DbSet初始化来自一个自定义查询。从查询初始化DbSet?

说明:

我DbSet将是只读的。

可以说我在我的数据库中有3个表格。我编写了一个SQL查询,可以在3个表上进行复杂的选择。现在我想用Entity Framework来查询查询结果。

我认为这是可能通过创建一个像这样的事情:

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

    } 

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

但我不知道怎么说来着的DbContext“嘿,用于检索DbSet的行,使用SQL查询!”。

NB:我不能和我不想修改数据库(我不能创建一个SQL视图为例)。

任何想法?

+1

http://stackoverflow.com/questions/10898344/execute-custom-sql-with -entity-framework – MajkeloDev

+0

它似乎不回答我的问题。我真的想使用实体框架数据集,因为我需要做一些OrderBy/Take/Skip等,我希望实体框架在数据库端执行此操作。我不想获取所有数据**,然后**制作Linq。 – Floc

+0

为什么你不能在你的上下文中添加3个'DbSet'属性(每个表有一个),并将它们与Linq加入? – DavidG

回答

0

您可以像正常一样创建您的dbContext,然后将SqlQuery用于“非实体”类型。

例如:

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

的关键点使用context.Database,那么你可以访问所有的表(即您的SQL帐户访问过,当然!),你可以定义你“的myType”以映射您选择的列。

+0

这应该是最后的手段 - 如果查询很复杂,维护一个硬编码的SQL字符串将很困难。最好创建适当的映射和关系。对于复杂的查询,视图将会无限更好 –

+0

确实如此,但正如他所说 - “我无法修改数据库,也不想修改数据库(例如,我无法创建sql视图)”。 –

+1

最后,我用这个答案。我返回context.Database.SqlQuery (“查询”),然后我做一些Take/Skip/OrderBy就可以了,查询之后执行。 这不是最好的方式,但它的工作原理。 – Floc

0

创建一个代表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)和名称(nvarchar的),那么这将作为工作的。

这里的主要观点是SQL查询可以包含连接或分组bys,或者只要自定义类和SQL中的最终选择具有相同的prop/fields ..包括类型就可以。那么它会为你绑定数据。

+0

是的,我知道该解决方案,但我需要使用Linq到实体上的查询结果。有了这个解决方案,我只能使用标准的Linq。这不是我想要的。 – Floc

+0

是的,你可以...只是在SQL中过滤它..使该基地,并返回它作为IQueriable ...或更好地写在Linq关闭DBsets的整个事情... – Seabizkit

-1

也许您可以尝试添加其他图层,例如存储库层:

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(); 
+0

你理解OP的问题错了,他甚至没有按照他希望的方式设置“ResultsRows”设置***。正如他所说的,他希望从一些自定义的SQL查询构建查询。正如其他答案建议使用'context.Database.SqlQuery <>(...)'。 – Hopeless

+0

编辑:读得太快。 这就是我想要的,但之前我需要检索“ResultsRows”而不提取所有记录。 – Floc

+0

@Floc根据您的要求,它不能成为您可以使用的解决方案。除非你以其他方式解决你的***原始***问题(不要试图从定制的SQL查询构建DbSet)。 – Hopeless