Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 返回linq查询的数据类型_C#_.net_Linq_Dynamic_Anonymous - Fatal编程技术网

C# 返回linq查询的数据类型

C# 返回linq查询的数据类型,c#,.net,linq,dynamic,anonymous,C#,.net,Linq,Dynamic,Anonymous,我有一个函数,它返回一个对象,该对象表示数据库中的一条记录以及其他列。我不想为这个对象创建一个单独的类,而是想知道是否还有其他方法,例如: public object GetRecord(string key) { var item = select new {column1, column2}; return item; } public void main() { var item = GetRecord(1); // I want to be ab

我有一个函数,它返回一个对象,该对象表示数据库中的一条记录以及其他列。我不想为这个对象创建一个单独的类,而是想知道是否还有其他方法,例如:

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;  
}
如果是.net 4.0,请使用关键字


是的,实际上还有很多其他方法,但我强烈建议你不要使用其中任何一种。处理这种情况的最佳选择是创建一个新的自定义类型,该类型保存您拥有的数据。到目前为止,它将是最容易维护的选项

匿名类型是专门为在单个方法的范围内使用而设计的。您正在与功能的设计作斗争,因此很难做到这一点,您很可能会失去Intellisense,性能很可能会受到影响,而需要返回并维护代码的可怜的sap将不知道发生了什么,也不知道如何调整查询

大多数替代解决方案的主要问题是丢失了编译时检查。如果查询删除参数、添加参数、更改类型等,则使用它的代码无法知道。在编写使用查询的代码时,您无法知道所有数据段是什么,它们的类型是什么,变量的名称是什么,等等。您需要担心编译器无法捕获的变量名称中的拼写错误,并且您将始终需要查看生成查询的方法的内部工作。您失去了将其视为黑盒或抽象的能力,这是非常重要的


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

除了补充其他答案之外,您还可以使用泛型来完成此操作。大概是这样的:

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

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

 var x = result[0].col1;  

此外,如果是.net 4.0,则可以使用元组,然后按item.Item1引用它。您可以使用对象的类型而不是简单的对象


你可以考虑使用PoCo库来完成这项工作。 您可以滚动自己的或使用现有的:

您的代码将如下所示:

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

   return item;
}
 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

我使用的是dynamic,但我假设列名称不会显示在intellisense中。但将在运行时工作。如果您在创建动态类型的其他作用域上,intellisense将不工作。对于intellisense,您需要使用无法在select子句中更改的具体类型。请参考Felipe的答案。我强烈反对在这些情况下使用dynamic。为初始开发和未来维护创建一个具体类型是值得的。使用dynamic,如果查询获取的数据与这些结果的使用方式不一致,没有Intellisense支持,并且性能受到影响,则不会出现编译时错误。这取决于。动态、Expando、匿名类型、对象、具体类型/接口,每种类型/接口都有一些优点/缺点,重要的是上下文。dynamic具有灵活性,但需要谨慎使用。我发现动态的使用大大提高了代码的可读性,这里面充满了语法错误。将新约束放在接口约束之后,删除对T的强制转换和选择。感谢您提供的提示@codesparkle。我在想,在这种情况下,我们真的需要选择关键字吗?