我有一个函数返回一个对象,该对象表示我的数据库中的记录以及其他列。我没有为这个对象创建一个单独的类,而是想知道是否还有其他方法,例如:
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;
}
答案 0 :(得分:8)
是的,还有其他方法(实际上有很多),但我强烈建议你不要使用它们中的任何一种。处理此案例的最佳选择是创建一个新的自定义类型,该类型保留您拥有的数据。它将是迄今为止最易维护的选择。
匿名类型专门设计用于单个方法的范围内。你正在与其他方面的功能设计作斗争,因此很难做到,你很可能会失去智能感知,性能很可能会受到影响,而且需要回来并维护代码的糟糕闷棍会不知道发生了什么或如何调整查询。
大多数备用解决方案的主要问题是您丢失了编译时检查。如果查询删除参数,添加参数,更改类型等,则使用它的代码无法知道。在编写代码以使用查询时,您无法知道所有数据是什么,它们的类型是什么,变量的名称是什么等等。您需要担心变量名称中的拼写错误,编译器可以抓住,你将始终需要查看生成查询的方法的内部工作。你失去了把它当作黑盒子或抽象的能力,这很重要。
如果您担心创建这些自定义类型所需的时间和精力,那么有许多自动化工具可用于根据数据库表或其他来源生成此类。
答案 1 :(得分:6)
如果是.net 4.0,请使用dynamic关键字。
public dynamic GetRecord(string key)
{
var item = select new {column1, column2};
return item;
}
答案 2 :(得分: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;
}
答案 3 :(得分:2)
只补充其他答案,你也可以使用泛型来做到这一点。像这样的东西:
public T GetRecord<T>(string key)
where T : IAnyInterfaceWithProperties, new
{
var item = select new T { PropertyOfInterface = value, Property2 = value2 };
return item;
}
答案 4 :(得分: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