2017-03-27 3 views
1

Ich schreibe Mock von DbSets und am Ende schreibe Serie von Code wie folgt.Generische Methodenextraktion

int rowCount = 0; 
var maxOrderId = EntityContainer.Set<Order>().Max(a => a.Id); 
var newOrders = EntityContainer.Set<Order>().Where(a =>a.Id == 0); 
foreach (var order in newOrders) 
{ 
    order.Id = ++maxOrderId; 
    rowCount++; 
} 

var maxServiceId = EntityContainer.Set<Service>().Max(a => a.Id); 
var newServices = EntityContainer.Set<Service>().Where(a => a.Id == 0); 
foreach (var service in newServices) 
{ 
    service.Id = ++maxServiceId; 
    rowCount++; 
} 

Es gibt mehr Entitäten in dieser Liste. Gibt es eine Möglichkeit, diese zu einer generischen Methode zu extrahieren? Etwas wie:

int GenerateID<Order>(); 

Ich versuchte dynamic verwenden, aber das Compiler beschwert sich, dass die Dynamik nicht in Lambda-Ausdrücke erlaubt.

+0

Vielleicht Ihnen Fall nicht relevant, aber Sie haben checked https://github.com/tamasflasich/effort bevor Sie Ihre eigene Implementierung einführen? –

Antwort

1

Sie müssen Ihre Objekte implementieren eine Schnittstelle wie gewährleisten würde:

interface IItem 
{ 
    int Id { get; set; } 
} 

Die GenerateId Methode würde dann wie folgt aussehen:

int GenerateID<T>(int rowCount) where T : IItem 
{ 
    var maxId = EntityContainer.Set<T>().Max(a => a.Id); 
    var newItems = EntityContainer.Set<T>().Where(a => a.Id == 0); 
    foreach (T item in newItems) 
    { 
     item.Id = ++maxId; 
     rowCount++; 
    } 

    return rowCount; 
} 

bearbeiten

zu vermeiden Sie, Schnittstellen hinzuzufügen, you cou ld Pass Accessorfunktion/Aktionen:

int GenerateId<T>(int rowCount, Func<T, int> getIdFunc, Action<T, int> setIdFunc) 
    where T : class 
{ 
    var maxId = EntityContainer.Set<T>().Max(getIdFunc); 
    var newItems = EntityContainer.Set<T>().Where(a => getIdFunc.Invoke(a) == 0); 
    foreach (T item in newItems) 
    { 
     setIdFunc.Invoke(item, maxId++); 
     rowCount++; 
    } 

    return rowCount; 
} 

Dann rufen wie:

rowCount = GenerateId<Order>(rowCount, o => o.Id, (o, id) => o.Id = id); 
rowCount = GenerateId<Service>(rowCount, o => o.Id, (o, id) => o.Id = id); 
+0

a.Id wäre kein gültiges Mitglied, es sei denn, wir verwenden einen Contraint der Klasse/Schnittstelle mit einem Mitglied als ID – Raghav

+0

Es würde nicht funktionieren, weil nichts sagt, dass 'T' eine' Id' hat. 'T' muss dann von einer Schnittstelle sein. –

+0

heißt das, ich muss alle meine Klassen mit dem IItem Interface erweitern ?? – Raghav

0

Wenn ich richtig verstehe Sie autoincrement Id für Ihr Modell benötigen.

Bitte lesen Sie diesen answer

Zusätzlich, wenn Sie begann ID festlegen möchten nur smth wie diese

public class Model 
{ 
    private static int m_Counter = 0; 
    // 
    public static ResetCounter(int start) 
    { 
     m_Counter=start; 
    } 
    public int Id { get; set; } 

    public Model() 
    { 
     this.Id = System.Threading.Interlocked.Increment(ref m_Counter); 
    } 
} 

verwenden und mit

Model.ResetCounter(maxServiceId)//optionally 
new Model {} //now When you create new object Model.Id should increment by itself 
Verwandte Themen