2010-09-24 16 views
46

¿Existe algún análogo cuerdo al LINQ (.NET) para Scala?LINQ análogos en Scala?

+3

Método específico LINQ adaptada a la Scala equivalente: http://stackoverflow.com/questions/8104846/chart-of-ienumerable-linq-equivalents-in-scala –

+0

LINQ para Scala (full API) y soporte de ejecución diferida: https://github.com/nicholas22/propelS – Scooterville

+2

Ver también: http://stackoverflow.com/a/8106548/192247. Podría ser útil. – missingfaktor

Respuesta

54

Depende de qué es exactamente lo que quiere decir con "LINQ". LINQ es muchas cosas.

La respuesta más obvia sería: simplemente use el puerto .NET de Scala. Le brinda acceso nativo completo a todo en .NET, que obviamente incluye LINQ.

Desafortunadamente, el puerto .NET de Scala se cayó hace un par de años. Afortunadamente, fue recogido nuevamente hace un par de meses, sin financiación oficial directamente de Microsoft. Puede esperar un lanzamiento en algún momento dentro del marco de tiempo de 2011/2012.

De todos modos, ¿qué es LINQ?

Se agregaron un par de funciones a .NET y específicamente a C# y VB.NET para LINQ. No son técnicamente parte de LINQ, pero son requisitos previos necesarios: tipo de inferencia, tipos anónimos (estructurales), expresiones lambda, tipos de función (Func<T...> y Action<T...>) y árboles de expresiones. Todos estos han estado en Scala durante mucho tiempo, la mayoría han estado allí para siempre.

También no forma parte directamente de LINQ, pero en C#, las expresiones de consulta LINQ se pueden usar para generar XML, para emular los literales XML de VB.NET. Scala tiene literales XML, como VB.NET.

Más específicamente, LINQ es

  • una especificación para un conjunto de operadores de consulta estándar
  • un conjunto de implementaciones para aquellos operadores (es decir IQueryable, LINQ-to-XML, LINQ-to-SQL, LINQ a Objetos)
  • una sintaxis embebido incorporado para LINQ comprensiones de consulta
  • una mónada

En Scala, como en casi cualquier otro lenguaje funcional (y de hecho también en casi cualquier otro lenguaje orientado a objetos, también), los operadores de consulta son simplemente parte de la API de colecciones estándar. En.NET, tienen un poco extraños nombres bits, mientras que en Scala, que tienen los mismos nombres estándar que tienen en otros idiomas: Select es map, Aggregate es reduce (o fold), SelectMany es flatMap, Where es filter o withFilter, orderBy es sort o sortBy o sortWith, y hay zip, take y takeWhile y así sucesivamente. Entonces, eso se ocupa tanto de la especificación como de la implementación de LINQ-to-Objects. Las bibliotecas XML de Scala también implementan las API de colecciones, que se encargan de LINQ-to-XML.

Las API SQL no están integradas en Scala, pero hay API de terceros que implementan la API de recopilación.

Scala sintaxis también se ha especializado para las API, pero a diferencia de Haskell, que trata de hacer que se vean como bloques C imperativas y C#, que trata de que se vean como las consultas SQL, Scala intenta que se vean como for bucles. Se llaman for comprensiones y son el equivalente a las comprensiones de las consultas de C# y las mónadas de comprensión de Haskell. (También reemplazan C# foreach y generadores (yield return)).

Pero si realmente quiere saber si hay análogos para LINQ en Scala, primero tendrá que especificar qué quiere decir exactamente con "LINQ". (Y, por supuesto, si usted quiere saber si son "sano", se tiene que definir eso, también.)

+19

La parte más útil de la respuesta es "Select is map, Where is filter or withFilter, orderBy es sort or sortBy or sortWith , ... ". Solo me faltan Count(), First(), FirstOrDefault(). –

+11

'size',' head', 'headOption.getOrElse'. Todos están en [scala.collection.Iterable] (http://www.scala-lang.org/api/current/scala/collection/Iterable.html) – stevej

+5

Una ventaja * enorme * que LINQ tiene es que admite la deconstrucción en Expression Trees que permite que toda la magia de LINQ2SQL "simplemente funcione". Dejando a un lado la sintaxis, este nivel de integración del árbol de expresiones no está actualmente disponible en Scala, por lo que todos los "proveedores correspondientes" también deben proporcionar su propio manejo de AST sin este nivel de abstracción. –

8

Existen muchas situaciones en Scala donde puede usar construcciones monádicas como una especie de lenguaje de consulta.

Por ejemplo, para consultar XML (en este caso, la extracción de direcciones URL de los enlaces en algunos XHTML):

def findURLs(xml: NodeSeq): Seq[URL] = 
    for { 
    a <- xml \\ "a" 
    href <- a attribute "href" 
    url <- href.text 
    } yield URL(url) 

Para un análogo de LINQ a SQL, lo más cercano es probablemente ScalaQuery. Para levantar un ejemplo a la derecha de la documentación:

val q4c = for { 
    u <- Users 
    o <- Orders if o.userID is u.id 
} yield u.first ~ o.orderID 
37

Todos LINQ IEnumerable extensiones están disponibles en Scala. Por ejemplo:

LINQ:

var total = orders 
     .Where(o => o.Customer == "myCustomer") 
     .SelectMany(o => o.OrderItems) 
     .Aggregate(0, (sum, current) => sum + current.Price * current.Count); 

Scala:

val total = orders 
     .filter(o => o.customer == "myCustomer") 
     .flatMap(o => o.orderItems) 
     .foldLeft(0)((s, c) => s + c.price * c.count) 
+0

@oleksii forAll y existe. http://www.scala-lang.org/docu/files/collections-api/collections.html – onof

10

Slick

es una moderna biblioteca de consultas de bases de datos y el acceso de Scala. (http://slick.typesafe.com/)

@table("COFFEES") case class Coffee(
    @column("COF_NAME") name: String, 
    @column("SUP_ID") supID: Int, 
    @column("PRICE") price: Double 
) 
val coffees = Queryable[Coffee] 


// for inserts use lifted embedding or SQL 
val l = for { 
    c <- coffees if c.supID == 101 
    //      ^comparing Int to Int! 
} yield (c.name, c.price) 


backend.result(l, session) 
.foreach { case (n, p) => println(n + ": " + p) }