【问题标题】:Return datatype of a linq query返回 linq 查询的数据类型
【发布时间】:2012-12-13 23:13:30
【问题描述】:

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

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

【问题讨论】:

    标签: c# .net linq dynamic anonymous


    【解决方案1】:

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

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

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

    如果您担心创建这些自定义类型所花费的时间和精力,可以使用许多自动化工具来根据数据库表或其他来源生成此类。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

      • 我使用的是动态的,但我认为列名不会出现在智能感知中。但会在运行时工作。
      • 如果您在创建动态类型的其他范围内,智能感知将不起作用。
      • 对于智能感知,您需要使用具体类型(不能在 select 子句中更改)。请参阅 Felipe 的回答。
      • 我强烈反对在这些情况下使用dynamic 。为初始开发特别是为将来的维护创建一个具体类型是值得的。使用dynamic,如果查询获取的数据与这些结果的使用方式不一致、没有 Intellisense 支持并且性能受到影响,则不会出现编译时错误。
      • 视情况而定。 dynamic,Expando,匿名类型,object,具体类型/接口,每个都有一些优点/缺点,重要的是上下文。动态带来了灵活性,但需要谨慎使用。我发现使用动态可以显着提高代码可读性的案例。
      【解决方案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;
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 这充满了语法错误。将new 约束放在接口约束之后,移除对T 和select 的强制转换。
        • 感谢@codesparkle 的提示。我在想在这种情况下,我们真的需要select关键字吗?
        【解决方案5】:

        您可能会考虑为此使用 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
        

        【讨论】:

          猜你喜欢
          • 2011-08-20
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多