Ich habe einige Word-Vorlagen (vielleicht Tausende). Jede Vorlage hat Zusammenführungsfelder, die aus der Datenbank gefüllt werden. Ich mag es nicht, separaten Code für jede Vorlage zu schreiben und dann die Anwendung zu erstellen und zu implementieren, wenn eine Vorlage geändert oder ein Feld in der Vorlage hinzugefügt wird!Erstellen Sie dynamische LINQ-Abfragen aus einer Zeichenfolge - Verwenden Sie Reflection?
Stattdessen versuche ich alle Merge-Felder in einer separaten XML-Datei zu definieren und für jedes Feld möchte ich die "Abfrage" schreiben, die bei Bedarf aufgerufen wird. EX:
- mergefield1 wird Abfrage "Case.Parties.FirstOrDefault.NameEn"
- mergefield2 nennen Abfrage "Case.CaseNumber"
- mergefield3 rufen Abfrage „Case.Documents.FirstOrDefault.DocumentContent.DocumentType nennen "
- Etc,
Also, für eine bestimmte Vorlage scannen ich seine Druckfelder, und für jedes Feld fusioniert ich nehme es` s ‚Abfragedefinition‘ und diese Anforderung an Datenbank machen EntityFramework und LINQ verwenden. Ex. es funktioniert für diese Abfragen: "TimeSlots.FirstOrDefault.StartDateTime" oder "Case.CaseNumber"
Dies wird eine Engine sein, die Word-Dokumente generiert und füllt es mit Seriendruckfeldern aus XML. Darüber hinaus funktioniert es für jede neue Vorlage oder neues Zusammenführungsfeld.
Jetzt habe ich eine Version mit Reflektion gearbeitet.
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
dynamic Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
string value = ""; //the value which will be filled with data from database
IEnumerable<string> linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Select(s => s.Name).ToList(); //get all linq methods and save them as list of strings
if (propertyName.Contains('.'))
{
string[] properies = propertyName.Split('.');
dynamic object1 = Entity;
IEnumerable<dynamic> Child = new List<dynamic>();
for (int i = 0; i < properies.Length; i++)
{
if (i < properies.Length - 1 && linqMethods.Contains(properies[i + 1]))
{
Child = type.GetProperty(properies[i]).GetValue(object1, null);
}
else if (linqMethods.Contains(properies[i]))
{
object1 = Child.Cast<object>().FirstOrDefault(); //for now works only with FirstOrDefault - Later it will be changed to work with ToList or other linq methods
type = object1.GetType();
}
else
{
if (linqMethods.Contains(properies[i]))
{
object1 = type.GetProperty(properies[i + 1]).GetValue(object1, null);
}
else
{
object1 = type.GetProperty(properies[i]).GetValue(object1, null);
}
type = object1.GetType();
}
}
value = object1.ToString(); //.StartDateTime.ToString();
}
return value;
}
Ich bin mir nicht sicher, ob dies der beste Ansatz ist. Hat jemand einen besseren Vorschlag oder hat jemand schon so etwas gemacht?
Um es zu kürzen: Die Idee ist es, generische linq Abfragen an die Datenbank aus einer Zeichenfolge wie: "Case.Parties.FirstOrDefault.NameEn".
Wenn ich Sie auf die richtige Art und Weise verstehe, würde ich Ihnen die Verwendung von Expression zum Erstellen von LINQ-Abfrage empfehlen.Diese Dinge können Sie erstellen, linq Anfrage in Laufzeit. https://msdn.microsoft.com/ru-ru/library/mt654263.aspx - hier ist ein Beispiel – Egorikas
Danke Egorikas. Eigentlich sind Expression ein bisschen komplex. Und ich bin mir nicht sicher, ob das auch auf mein Problem zutrifft. Aber ich werde noch einmal auf Ausdrücke schauen. – drill