2012-04-23 13 views
6

Zur Zeit erstelle ich eine Webschnittstelle für FreeRADIUS. Es ist nur eine kleine App, um Mutationen für Shell- und SQL-faule Mitarbeiter zu vereinfachen. Ich habe ein Entity Framework-Modell für die Datenbank erstellt und möchte es mithilfe des Fassadenmusters kapseln. Also habe ich eine DTO-Klasse namens Account erstellt. Es speichert Daten, die aus drei verschiedenen Tabellen aggregiert sind. Dies ist, was Account.cs wie folgt aussieht:Bleib DRY mit DTO's

public class Account 
{ 
    public int? Id { get; set; } 
    public string UserName { get; set; } 
    public string Password { get; set; } 
    public string GroupName { get; set; } 
    public string IpAddress { get; set; } 
    public string Route { get; set; } 
} 

diese Methode wird nur ich zusammenbauen und einen einzigen Konto-DTO zurückzukehren.

Account Get(string userName) 
{ 
    // Get the values from the database. 
    var check = _entities.Checks.Single(x => x.UserName == userName); 
    var userGroup = _entities.UserGroups.Single(x => x.UserName == userName); 
    var ipReply = _entities.Replies.Single(x => x.UserName == userName && x.Attribute == "Framed-IP-Address"); 
    var routeReply = _entities.Replies.Single(x => x.UserName == userName && x.Attribute == "Framed-Route"); 

    // Populate the DTO 
    var account = new Account 
    { 
     UserName = check.UserName, 
     Password = check.Value, 
     GroupName = userGroup.GroupName 
    }; 

    if (ipReply != null) account.IpAddress = ipReply.Value; 
    if (routeReply != null) account.Route = routeReply.Value; 

    return account; 
} 

Und das ist die Methode, um die Datenbank von einem Benutzer übermittelten Konto-DTO

void Update(Account account) 
{ 
    // Get the values from the database. Again. 
    var check = _entities.Checks.Single(x => x.UserName == account.UserName); 
    var userGroup = _entities.UserGroups.Single(x => x.UserName == account.UserName); 
    var ipReply = _entities.Replies.Single(x => x.UserName == account.UserName && x.Attribute == "Framed-IP-Address"); 
    var routeReply = _entities.Replies.Single(x => x.UserName == account.UserName && x.Attribute == "Framed-Route"); 

    // Update the possible attributes 
    check.Value = account.Password; 
    userGroup.GroupName = account.GroupName; 
    ipReply.Value = account.IpAddress; 
    routeReply.Value = account.Route; 

    _entities.SaveChanges(); 
} 

Wie Sie sehen können zu aktualisieren, verwende ich die exakt gleichen Codedaten aus der Datenbank abgerufen werden. Wie kann ich diesen Code DRY?

+0

'Fabrik :: GetCheck (String Username)', 'Fabrik :: GetUserGroup (String Username)', ...? –

+0

Wie tief durch deine Schichten bewegt sich dieser DTO? Geht es von der UI-Ebene bis hinunter zur DB-Ebene? –

+0

Es ist eine MVC-Webanwendung (jede Ansicht hat ein Ansichtsmodell) Das DTO wird von einem solchen Ansichtsmodell (in diesem Fall sieht es genau wie Account.cs aus) erstellt und an die Fassade übertragen (die die obigen Methoden enthält). – Sandro

Antwort

1

Warum nicht einfach Shared Code zu lokaler Klasse zu extrahieren

class AcccountFieldsByName { 
// check, userGroup, ipReply, routeReply 

    static AcccountFieldsByName Read(... _entities, string userName)  
    { 
    return new AcccountFieldsByName { 
     check = _entities.Checks.Single(x => x.UserName == userName), 
     userGroup = _entities.UserGroups.Single(x => x.UserName == userName), 
     ipReply = _entities.Replies.Single(x => x.UserName == userName && x.Attribute == "Framed-IP-Address"), 
     routeReply = _entities.Replies.Single(x => x.UserName == userName && x.Attribute == "Framed-Route"), 
     } 
    } 
}