209 Stimmen

Ergebnisse vom anonymen Typ zurückgeben?

Was ist die beste Methode, um mit Linq to SQL Ergebnisse aus mehreren Tabellen zurückzugeben, und zwar anhand des folgenden einfachen Beispiels?

Angenommen, ich habe zwei Tabellen:

Dogs:   Name, Age, BreedId
Breeds: BreedId, BreedName

Ich möchte alle Hunde mit ihren BreedName . Ich sollte alle Hunde mit so etwas ohne Probleme bekommen:

public IQueryable<Dog> GetDogs()
{
    var db = new DogDataContext(ConnectString);
    var result = from d in db.Dogs
                 join b in db.Breeds on d.BreedId equals b.BreedId
                 select d;
    return result;
}

Aber wenn ich Hunde mit Rassen will und das versuche, habe ich Probleme:

public IQueryable<Dog> GetDogsWithBreedNames()
{
    var db = new DogDataContext(ConnectString);
    var result = from d in db.Dogs
                 join b in db.Breeds on d.BreedId equals b.BreedId
                 select new
                        {
                            Name = d.Name,
                            BreedName = b.BreedName
                        };
    return result;
}

Jetzt erkenne ich, dass der Compiler nicht lassen Sie mich einen Satz von anonymen Typen zurückgeben, da es Dogs erwartet, aber gibt es eine Möglichkeit, dies zurückzugeben, ohne einen benutzerdefinierten Typ zu erstellen? Oder muss ich meine eigene Klasse für DogsWithBreedNames und geben Sie diesen Typ in der Select? Oder gibt es einen anderen, einfacheren Weg?

0 Stimmen

Nur so aus Neugier, warum zeigen alle Linq-Beispiele mit anonymen Typen, wenn sie nicht funktionieren. Z.B., dieses Beispiel tut foreach (var cust in query) Console.WriteLine("id = {0}, City = {1}", cust.CustomerID, cust.City);

0 Stimmen

@Hot Licks - die Tabelle Customer in diesen Beispielen ist eine Entität, die durch eine Klasse dargestellt wird. Das Beispiel scheint nur nicht die Definitionen dieser Klassen zu zeigen.

0 Stimmen

Sie erfahren auch nicht, dass ein Compilerfehler "var" durch den Klassennamen ersetzt.

9voto

xcopy Punkte 2178

Sie könnten etwa so vorgehen:

public System.Collections.IEnumerable GetDogsWithBreedNames()
{
    var db = new DogDataContext(ConnectString);
    var result = from d in db.Dogs
                 join b in db.Breeds on d.BreedId equals b.BreedId
                 select new
                        {
                            Name = d.Name,
                            BreedName = b.BreedName
                        };
    return result.ToList();
}

8voto

joshperry Punkte 39356

Nein, man kann keine anonymen Typen zurückgeben, ohne etwas zu tricksen.

Wenn Sie nicht C# verwenden würden, würde das, wonach Sie suchen (die Rückgabe mehrerer Daten ohne konkreten Typ), als Tupel bezeichnet.

Es gibt eine Vielzahl von C#-Tupel-Implementierungen, die die eine hier gezeigt würde Ihr Code folgendermaßen funktionieren.

public IEnumerable<Tuple<Dog,Breed>> GetDogsWithBreedNames()
{
    var db = new DogDataContext(ConnectString);
    var result = from d in db.Dogs
                 join b in db.Breeds on d.BreedId equals b.BreedId
                 select new Tuple<Dog,Breed>(d, b);

    return result;
}

Und auf der Website des Anrufers:

void main() {
    IEnumerable<Tuple<Dog,Breed>> dogs = GetDogsWithBreedNames();
    foreach(Tuple<Dog,Breed> tdog in dogs)
    {
        Console.WriteLine("Dog {0} {1}", tdog.param1.Name, tdog.param2.BreedName);
    }
}

7 Stimmen

Das funktioniert nicht. Wirft ein NotSupportedException : Nur parameterlose Konstruktoren und Initialisierer werden in LINQ to Entities unterstützt

1 Stimmen

Richtig, die Tuple-Klasse hat keinen Standardkonstruktor und wird auf diese Weise nicht korrekt mit LINQ to Entities funktionieren. Sie funktioniert jedoch gut mit LINQ to SQL, wie in der Frage beschrieben. Ich habe das nicht ausprobiert, aber es könnte funktionieren mit ... select Tuple.Create(d, b) .

1 Stimmen

Da Tupel von einigen LINQ-Anbietern nicht unterstützt werden, könnten Sie nicht einen anonymen Typ auswählen, konvertieren Sie es in IEnumerable, dann wählen Sie ein Tupel aus, dass?

4voto

Sergey Punkte 240

Jetzt erkenne ich, dass der Compiler nicht lassen Sie mich einen Satz von anonymen Typen zurückgeben, da es Dogs erwartet, aber gibt es eine Möglichkeit, dies zurückzugeben, ohne einen benutzerdefinierten Typ zu erstellen?

Verwendung verwenden Objekt um eine Liste von Anonymous-Typen zurückzugeben, ohne einen eigenen Typ zu erstellen. Dies funktioniert ohne den Compilerfehler (in .net 4.0). Ich habe die Liste an den Client zurückgegeben und sie dann in JavaScript geparst:

public object GetDogsWithBreedNames()
{
    var db = new DogDataContext(ConnectString);
    var result = from d in db.Dogs
                 join b in db.Breeds on d.BreedId equals b.BreedId
                 select new
                        {
                            Name = d.Name,
                            BreedName = b.BreedName
                        };
    return result;
}

1 Stimmen

Meiner Meinung nach wäre es korrekter und lesbarer, wenn Ihre Methodensignatur wie folgt aussehen würde: public IEnumerable<object> GetDogsWithBreedNames()

4voto

Daniel Punkte 10511

Das beantwortet zwar nicht genau Ihre Frage, aber Google hat mich anhand der Schlüsselwörter hierher geführt. So könnten Sie einen anonymen Typ aus einer Liste abfragen:

var anon = model.MyType.Select(x => new { x.Item1, x.Item2});

3voto

Andrey Shchekin Punkte 20287

Wählen Sie einfach Hunde aus und verwenden Sie dann dog.Breed.BreedName sollte dies gut funktionieren.

Wenn Sie viele Hunde haben, verwenden Sie DataLoadOptions.LoadWith, um die Anzahl der Datenbankaufrufe zu reduzieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X