2012-12-28 133 views
5

我有一个函数返回一个对象,该对象表示我的数据库中的记录以及其他列。相反,该对象创建一个单独的类的,我想知道是否有另一种方式,例如:返回linq查询的数据类型

public object GetRecord(string key) 
{ 
    var item = select new {column1, column2}; 

    return item; 
} 

public void main() 
{ 
    var item = GetRecord(1); 

    // I want to be able to reference column1 on item. 
    var x = item.column1; 
} 

回答

8

是的,还有其他的方法(其实很多),但我强烈建议你不要使用它们中的任何一个。处理这种情况的最佳选择是创建一个新的自定义类型,以保存您拥有的数据。这将是最可维护的选择。

匿名类型专门设计用于单个方法的范围内。你正在与功能的设计进行斗争,否则将很难做到,你很可能会失去Intellisense,性能很可能会受到影响,而需要返回并维护代码的可怜的sap会不知道发生了什么或者如何调整查询。

大多数备用解决方案的主要问题是您失去了编译时检查。如果查询删除参数,添加参数,更改类型等,则使用它的代码无法知道。当编写代码来使用查询时,你无法知道所有的数据块是什么,它们的类型是什么,变量的名字是什么等等。你需要担心变量名中的拼写错误,编译器可以没有赶上,并且您一直需要查看生成查询的方法的内部运作情况。你失去了把它当作黑盒子或抽象的能力,这很重要。

如果您担心创建这些自定义类型需要花费的时间和精力,那么会有许多自动化工具用于生成基于数据库表或其他来源的类。

+1

+1,我没有理由不创建自定义类型。 –

6

如果是.NET 4.0中使用dynamic关键字。

public dynamic GetRecord(string key) 
{ 
    var item = select new {column1, column2}; 

    return item; 
} 
+0

我使用动态,但我假设列名wi将不会出现在intellisense中。但会在运行时工作。 – Arcadian

+0

如果您在其他范围内创建了动态类型,则智能感知不起作用。 –

+0

对于intellisense,您需要使用具体类型(在select子句中不能更改)。请参阅Felipe的回答。 – Tilak

2

只补充其他答案,您也可以使用泛型来做到这一点。是这样的:

public T GetRecord<T>(string key) 
    where T : IAnyInterfaceWithProperties, new 
{ 
    var item = select new T { PropertyOfInterface = value, Property2 = value2 }; 

    return item; 
} 
+1

这充满了语法错误。在接口约束之后放置'new'约束,将类型转换为'T'和'select'。 – Adam

+0

谢谢你的提示@codesparkle。我在想,在这种情况下,我们真的需要'select'关键字吗? –

3

此外,如果它是.NET 4.0,你可以使用一个Tuple<object,object>然后item.Item1引用它。您可以使用对象的键入而不是简单的object

public Tuple<Column1Type,Column2Type> GetRecord(string key) 
{ 
    var item = select new Tuple<Column1Type,Column2Type>(column1, column2); 

    return item; 
} 
1

你可能会考虑使用POCO库这一点 - 会做你想要什么。

你可以滚你自己或使用其中一个已经可用:

http://code.google.com/p/dapper-dot-net/

你的代码,然后将是这个样子:

var result = connection.Query("select col1, col2 from table1"); 

var x = result[0].col1; 

Drapper也可以让你有一个强大的类型例如:

var result = connection.Query<myType>("select col1, col2 from table1"); 

' Now result is a list of myType