2016-12-07 2 views
0

Ich möchte eine Zeichenfolge-ID mit einem Join überschreiben, wenn Sie eine Abfrage ausführen. Im Moment verwende ich das Datenbankmodell als Ansichtsmodell, wie Visual Studio automatisiert. Dies ist für meine Verwendung durchaus akzeptabel, aber ich muss den Benutzernamen nicht ihre ID anzeigen. Für einen einzigen Kandidaten habe ich eine so erreicht für die Detailansicht:Join und überschreiben Sie einen Modellwert mithilfe von LINQ

var ret = (from c in db.candidates 
      where c.candidate_id == id 
      join u in db.Users on c.createdby equals u.Id 
      select new { c, u.UserName } 
      ).FirstOrDefault(); 

candidate theCandidate = ret.c; 
theCandidate.createdby = ret.UserName; // Override with the username 

Kann ich die theCandidate.createdby = ret.UserName in der LINQ-Abfrage gemacht?
Oder sollte ich das anders angehen? (es scheint mir, dass die Ansicht den anonymen Typen vorbei zu schaffen ist nicht ideal)

bearbeiten
Oder soll ich ändern, nur das Datenbankmodell implizit die Verbindung haben:

class Candidate 
{ 
    ... 

    [ForeignKey("createdby")] 
    public virtual ApplicationUser CreatedByUser { get; set; } 
} 

Antwort

2

Dieser Dies ist ein typischer Fall, der die Nützlichkeit von ViewModels beweist: Ihre Ansicht benötigt etwas anderes im Vergleich zu dem, was Ihre Datenbank liefert.

Auch legt der Code etwas in createdby, die dort nicht hingehört, vorausgesetzt, die Datentypen es erlauben

Vielleicht ist es Zeit, diese zu verwenden gewöhnungs (was ist, wenn createdby ist ein int?):

public class CandidateViewModel 
{ 
    // add properties that the View needs from database candidates table 
    string Username { get; set; } // the additional prop 

    public CandidateViewModel(candidate c, string username) 
    { 
     // ... obvious code here 
    } 
} 

Und dann

var ret = (from c in db.candidates 
      where c.candidate_id == id 
      join u in db.Users on c.createdby equals u.Id 
      select new CandidateViewModel(c, u.UserName) 
     ).FirstOrDefault(); 

Edit:

Mit dem neuen Fremdschlüssel in Ort, den Sie so etwas wie dies versuchen könnte:

// using System.Data.Entity;   <-- add this on top 
var ret = (from c in db.candidates 
      where c.candidate_id == id 
      select c 
     ) 
      .Include("CreatedByUser") // or "createdby" - not sure 
      .FirstOrDefault(); 

Mit dem im Ort, versuchen ret.CreatedByUser.UserName in der Steuerung, oder sogar in der Ansicht. Beachten Sie, dass mein EF ein wenig eingerostet ist, also müssen Sie möglicherweise einige Dinge ausprobieren, um es richtig zu machen.

+0

Ja, das habe ich mir ein bisschen gedacht ... und dann habe ich mich gefragt, naja, wenn ich jedes Feld kopieren muss (wo du "offensichtlichen Code" geschrieben hast), ist das nicht genauso schlimm? Ich möchte kein Eins-zu-eins-Mapping für alle Variablen schreiben. Wenn ich ein neues hinzufüge, muss ich dem db-Modell und dem Ansichtsmodell hinzufügen und dann eine Zeile schreiben, um es zu kopieren. – noelicus

+0

Oder ist es gute Form, nur (in diesem Fall) den Kandidaten aus DB-Modell zu kopieren, um Modell zu sehen: 'this.candidate = c' – noelicus

+0

@noelicus aber Sie können Vererbung hier setzen gemeinsame Eigenschaften in Basis-Klassenansicht Modell und erben es und zusätzliche Eigenschaft in kindclassviewmodel, sinnvoll? –