Linq to Entities-Gruppe Durch (ÄUßERE GELTEN) "oracle 11.2.0.3.0 nicht unterstützt gelten"

Ich habe das code sample unten, welche Abfragen eine Liste der Produkte.

 var productResults = Products.Where((p) => refFilterSequence.Contains(p.Ref))
                .GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First()).ToList();


Dies funktioniert genau wie erwartet und gibt die 4 Zeilen möchte ich bei Verwendung einer in-memory Sammlung, aber beim laufen gegen die Oracle-Datenbank:

.GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First())

Löst dies ein Fehler zu sagen, die ich verwenden sollte FirstOrDefault nicht unterstützt werden in einer Oracle-Datenbank. Der Fehler oracle 11.2.0.3.0 nicht unterstützt gelten geworfen erhält. Googleing, offenbart auf CodePlex: https://entityframework.codeplex.com/workitem/910.

Dies tritt, wenn die folgenden Binärdateien:

  • EntityFramework 6.0.0.0
  • Oracle.ManagedDataAccess 4.121.2.0
  • Oracle.ManagedDataAccess.EntityFramework 6.121.2.0
  • .Net Framework 4.5.1

Die Datenbank ist eine Oracle 11.2.0.3.0 Datenbank.

Generierte sql verwendet OUTER APPLY (siehe Bild unten), das nicht unterstützt wird von der 11.2.0.3.0 von der Oracle-version so, warum ist EF/Oracle.ManagedDataAccess versucht, es zu benutzen? Gibt es eine Möglichkeit zu sagen, das EF nicht zu benutzen, die ANZUWENDEN keyword?

Linq to Entities-Gruppe Durch (ÄUßERE GELTEN)

Dieser Seite weiter unten sagt, dass die GELTEN-Unterstützung in Oracle 12c Release 1, aber ich kann nicht aktualisieren, alle meine Datenbanken nur eine GRUPPE machen, die VON der Arbeit.
http://www.oracle.com/technetwork/database/windows/newfeatures-084113.html

Scheint es, dass dies ein bekanntes Problem (Bekannte Probleme in SqlClient für Entity Framework):

Im folgenden werden einige typische Szenarien können dazu führen, dass die
Vorhandensein von CROSS APPLY-und/oder OUTER APPLY-Operatoren in der Ausgabe
Abfrage:

  • LINQ-Abfragen, die Gruppierung der Methoden akzeptieren, dass ein element-Selektor.

Bevor ich Sie resort zum erstellen einer Ansicht (hätte ich eine Ansicht erstellen, die auf mehrere Datenbanken), kann jemand sehen, noch eine andere Lösung?

Für alle interessierten, die SQL -, die tun, was ich will, gegen diese Datenbank version würde in etwa wie folgt Aussehen:

select *
from ( select  RANK() OVER (PARTITION BY sm.product ORDER BY refs.map)      ranking, sm.*
            from    schema.table sm,
                    (
                        select 'R9' ref, 0 map from dual
                        union all
                        select 'R1' ref, 1 map from dual
                        union all
                        select 'R6' ref, 2 map from dual
                    ) refs
            where   sm.ref= refs.ref                               
          ) stock
where ranking  = 1

Wird der code schließlich in eine service-Klasse übergeben und die OData-controller in Web-API.
Das Beispiel unten verwendet die demo-Daten, die eigentliche Datenbank hat rund 700.000 Datensätze,
so möchte ich vermeiden, der die Abfrage ausführt und lassen OData Griff Seite Grenzen und weiter filtern.

using System;
using System.Collections.Generic;
using System.Linq;

namespace DemoApp
{
    class Program
    {
        public class Product
        {
            public string Ref { get; set; }
            public string Code { get; set; }
            public int Quantity { get; set; }
        }

        //demo data
        static readonly List<Product> Products = new List<Product>
        {
            new Product { Ref = "B2", Code = "ITEM1", Quantity = 1},
            new Product { Ref = "R1", Code = "ITEM1", Quantity = 2},
            new Product { Ref = "R9", Code = "ITEM1", Quantity = 3},
            new Product { Ref = "R9", Code = "ITEM2", Quantity = 4},
            new Product { Ref = "R6", Code = "ITEM2", Quantity = 5},
            new Product { Ref = "B2", Code = "ITEM3", Quantity = 6},
            new Product { Ref = "R1", Code = "ITEM3", Quantity = 7},
            new Product { Ref = "R9", Code = "ITEM3", Quantity = 8},
            new Product { Ref = "B2", Code = "ITEM4", Quantity = 9},
            new Product { Ref = "X3", Code = "ITEM4", Quantity = 10},
            new Product { Ref = "B8", Code = "ITEM5", Quantity = 10},
            new Product { Ref = "R6", Code = "ITEM5", Quantity = 12},
            new Product { Ref = "M2", Code = "ITEM5", Quantity = 13},
            new Product { Ref = "R1", Code = "ITEM5", Quantity = 14},
        };

    static void Main(string[] args)
    {
        //this array is of variable length, and will not always contain 3 items.
        var refFilterSequence = new List<string> {"R9", "R1", "R6"};

        var results = GetProductsForODataProcessing(refFilterSequence);

        //some further filtering may occur after the queryable is returned.
        //the actual implmentation is an OData Web API, so filters, expansions etc could be added.

        //results = results.Where(p => p.Quantity > 2);

        results.ToList().ForEach(p => Console.WriteLine("RANK:{0}\tREF:{1}\tCode:{2}\tQty:{3}", "?", p.Ref, p.Code, p.Quantity));
        Console.ReadLine();
    }

    static IQueryable<Product> GetProductsForODataProcessing(List<string> filterSequence )
    {
        var productResults = Products.Where((p) => filterSequence.Contains(p.Ref))
            .GroupBy(g => g.Code, (key, g) => g.OrderBy(whp => whp.Ref).First()).AsQueryable();

        return productResults;               
    }
}


//Example Output
//.......................
//REF:R1 Code:ITEM1 Qty:2
//REF:R6 Code:ITEM2 Qty:3
//REF:R1 Code:ITEM3 Qty:7
//REF:R1 Code:ITEM5 Qty:14
InformationsquelleAutor philreed | 2015-04-17
Schreibe einen Kommentar