2013-04-25 39 views
1

TL表的访问; DR我使用EntityFramework 5.0Oracle,需要查询表中的两列只能用指数与两列NVL编写SQL查询,而不完全

细节经过数小时的尝试...我会尽量组织它尽可能。

所需的SQL查询应该是:

SELECT t.Code, NVL(t.Local, t.Global) Description 
FROM Shows t 
Where t.Code = 123 

那么是什么问题?如果我想要使用Context.Shows.Parts.SqlQuery(query)我必须返回整行(*),但后来我得到表访问完整,所以我必须只返回所需的列。

接下来的事情(其实有很多的尝试以下...之前),我已经试过这给出了一个非常紧密的结果是使用空合并运算??):

Context.Shows.Where(x => x.Code == 123) 
      .Select(x => new { x.Code, Description = x.Local ?? x.Global); 

但它使用的SQL很复杂,使用case & when而不是使用我的索引Code, Nvl(Local, Global)这是至关重要的!

我的下一步是使用Database.SqlQuery

context.Database.SqlQuery<Tuple<int, string>>("the Raw-SQLQuery above"); 

但我得到一个错误,Tuple不能是抽象的,必须有默认的构造函数(事实并非如此)。

我不喜欢最后一步是创建类它只有这两个性质在(Code, Description),现在... ...它的伟大工程,但我不想写一个类一样,每个查询。

想法?

+2

您可以尝试编写自己的Tuple实现,该实现具有默认的构造函数并且是一个类。 – jure 2013-04-25 09:38:40

+0

_“我不喜欢创建类的最后一步......但我不想为每个查询编写类”_ – gdoron 2013-04-25 09:42:48

+0

您不必为每个查询编写新类,但只写一个通用的可重用类,并在您的示例中使用它作为您正在使用的Touple。 – jure 2013-04-25 09:48:56

回答

2

这是一个没有答案的答案。

我想无论你尝试什么,你都做不到。即使你定义自己的可变通用的元组,它会因为属性的名称必须match the name of the column失败:

SqlQuery类(字符串,对象[]):创建一个原始的SQL查询给定的将 回报元素泛型类型。该类型可以是任何类型的 ,其属性与查询返回的 返回的列的名称相匹配,也可以是简单的基本类型。

我认为你能做的最好是创建自己的泛型方法通过经典CommandExecuteReader方式查询数据库。未经测试,但您的想法:

public static IEnumerable<Tuple<T>> SqlQuery<T>(this DbContext context, string sql) 
{ 
    using(var connection = new SqlConnection(context.Database.Connection.ConnectionString)) 
    using (var command = new SqlCommand(sql, connection)) 
    { 
     var reader = command.ExecuteReader(); 
     while (reader.NextResult()) 
     { 
      yield return new Tuple<T>((T)reader[0]); 
     } 
    } 
} 
public static IEnumerable<Tuple<T1, T2>> SqlQuery<T1, T2>(this DbContext context, string sql) 
{ 
    using (var connection = new SqlConnection(context.Database.Connection.ConnectionString)) 
    using (var command = new SqlCommand(sql, connection)) 
    { 
     var reader = command.ExecuteReader(); 
     while (reader.NextResult()) 
     { 
      yield return new Tuple<T1, T2>((T1)reader[0], (T2)reader[1]); 
     } 
    } 
}