| Bernhard's profileBernhard Grojer - BlogPhotosBlogLists | Help |
|
|
February 12 Virtual CD/DVD – Windows 7
February 04 Jobs, Jobs, Jobs, …
January 27 Generic Delegates: Func<T>Im letzten Posting habe ich die Möglichkeiten beschrieben einen Delegate als Paramter zu akzeptieren. 1: ... Demo1.GetDemos( 2: delegate(Demo d) 3: { 4: return (d.Active && d.Name == "Test"); 5: } 6: );
1: Func<int, bool> f = (i) => i == 1; 2: var res = f(10);Variable “f” beinhaltet nun unsere eigentliche Logik (Zuweisung über Lambda-Schreibweise). Dessen Aufruf ist dann denkbar einfach und natürlich können wir auch hier wieder Funktionen definieren die einen Parameter Func<T> nimmt. January 26 Predicate<T> in C# 3.0
1: public static class Demo1 2: { 3: public static List<Demo> GetDemos(Predicate<Demo> p) 4: {5: var lst = GetList(); //Ladet eine Liste die gefiltert werden soll 6: foreach (v i in lst) 7: {8: if (p(i)) 9: yield return i; 10: } 11: } 12: }Aufruf: 1: var lst = Demo1.GetDemos(2: delegate(Demo d) 3: {4: return (d.Active && d.Name == "Test"); 5: } 6: );Und somit sollten auch die Technolgien die hinter LINQ Stecken wieder etwas January 23 LINQ: JoinIn einem Linq Model kann man ein “Join” relativ einfach hinbekommen wenn die Einzelnen Elemente bereits Beziehungen haben. (Stichwort EntitySet<T>) 1: var query = from o in DB.Orders 2: select new 3: { 4: Name = o.Customer.CompanyName, 5: OrderID = o.OrderID 6: };Doch oftmals gibts genau diese Beziehung zwischen den Objekten nicht (hier zwischen Customer u. Order). 1: var query = from o in DB.Orders 2: join c in DB.Customers on o.CustomerID equals c.CustomerID 3: select new 4: { 5: Name = c.CompanyName, 6: OrderID = o.OrderID 7: };Download Sample: LinqJoin.zip VSONE – München – 10. bis 13. Feb. 2009
Delegates, anonyme Methoden und Lambda Expression waren Ihnen immer schon ein Rätsel? Sie wollen mit weniger Code MEHR tun? Holen Sie sich noch einen der letzten Plätze. January 20 Live MeshWindows Live Mesh, zu finden unter https://www.mesh.com/ ist eine flexible Möglicheit Daten über mehrere Systeme zu synchronisieren. zB Favoriten können damit mit 2 klicks a) im Internet verfügbar gemacht werden Im Moment ist das Produkt noch Beta (und bietet 5 GB kostenlosen Speicher!) Wie findet Ihr das Teil? January 01 HAPPY NEW YEAR
December 16 SkyDrive - Favorites synchronisieren mit Internet ExplorerDas SkyDrive Team hat unter anderem gebloggt, dass man die Favoriten im Internet Explorer mit SkyDrive syncronisieren kann. Leider klappt das nicht ganz (oder ich bin zu blöd dafür)
Die neue Toolbar fürn IE hat zwar die Option eine (neue) öffentliche Favorite online (im SkyDrive) zur Verfügung zu stellen. Aber mit synchronisieren der (privaten) Favoriten siehts bitter aus Hats schon jemand geschafft? December 04 Windows Live SkyDrive – 25 GB gratis
November 27 IDAY – .net 3.5 Präsentation (ppedv Wien)
October 17 LINQ Provider – Vom Ausdruck zum Ergebnis – Teil 4
Da wir nun die Basisklassen soweit abgesteckt haben können wir nun dazu übergehen uns um die Implementierung zu kümmern. public class Employee { public string FirstName { get; set; } public string LastName { get; set; } public bool Active { get; set; } } … und den dazu passenden Provider … public class EmployeeProvider : QueryProvider { public override object Execute(Expression expression) { //Kommt noch … Außerdem ist es noch “hilfreich”, wenn wir uns einen DataContext (sie kennen so etwas eventuell aus LINQ-TO-SQL) erzeugen: public class NorthwindDataContext { QueryProvider Provider = new EmployeeProvider(); public Query<Employee> Employees { get { return new Query<Employee>(Provider); } } } Und somit können wir nun unsere ersten Abfragen gegen unsere eigene Datenquelle erzeugen. var context = new NorthwindDataContext(); var res = from e in context.Employees where e.Active orderby e.LastName select e; Wenn Sie jetzt einen Breakpoint in die Provider.Execute Methode setzen und die Anwendung starten bekommen wir nun den von LINQ erzeugten ExpressionTree als Parameter in die Execute-Methode. Diesen ExpressionTree gilt es nun noch auszuwerten, den gang zur Datenquelle zu machen und die Rückgabe zu erstellen. Die Execute(….) Methode bereitet einen LINQ Abfrage vor die wir entsprechend unseres ExpressionTrees in der ProcessExpression(….) Methode verändern/ersetzen. public override object Execute(Expression expression) { //Create query var doc = XDocument.Load(file); var query = from emp in doc.Descendants("Employee") select emp; //Edit query ProcessExpression(expression, ref query); //Transform Data var res = GetElementsFromXml(query); //Return Data return res; } In ProcessEpxression editieren wir nun die Linq To Xml Abfrage (natürlich könnte man hier auch einen SQL Abfrage zusammensetzen mit einem StringBuilder etc.) und haben am Ende die fertige Abfrage für die XML Datei. private void ProcessExpression(Expression e, ref IEnumerable<XElement> resultQuery) { if (e is UnaryExpression) { var exp = e as UnaryExpression; ProcessExpression(exp.Operand, ref resultQuery); } else if (e is LambdaExpression) { var exp = e as LambdaExpression; ProcessExpression(exp.Body, ref resultQuery); } else if (e is BinaryExpression) { var exp = e as BinaryExpression; if (exp.NodeType == ExpressionType.Equal) { string attrib = string.Empty; object value = null; if (exp.Left is MemberExpression) { var left = exp.Left as MemberExpression; attrib = left.Member.Name; value = Expression.Lambda(exp.Right).Compile().DynamicInvoke(); } else if (exp.Right is MemberExpression) { var right = exp.Right as MemberExpression; attrib = right.Member.Name; value = Expression.Lambda(exp.Left).Compile().DynamicInvoke(); } else { throw new NotImplementedException(); } //ChangeTargetExpressionTree resultQuery = from emp in resultQuery where emp.Attribute(attrib).Value == GetValueFromMapping(attrib, value).ToString() select emp; } } else if (e is MethodCallExpression) { var exp = e as MethodCallExpression; string attrib, value = string.Empty; if (exp.Type == typeof(IOrderedQueryable<Employee>)) { attrib = (((exp.Arguments[1] as UnaryExpression).Operand as LambdaExpression).Body as MemberExpression).Member.Name; resultQuery = from emp in resultQuery orderby emp.Attribute(attrib).Value select emp; } if (exp.Method.DeclaringType == typeof(string)) { value = Expression.Lambda(exp.Arguments[0]).Compile().DynamicInvoke().ToString(); attrib = (exp.Object as MemberExpression).Member.Name; switch (exp.Method.Name) { case "Contains": resultQuery = from emp in resultQuery where emp.Attribute(attrib).Value.Contains(value) select emp; break; case "StartsWith": resultQuery = from emp in resultQuery where emp.Attribute(attrib).Value.StartsWith(value) select emp; break; default: throw new NotImplementedException(); } } else { foreach (var current in exp.Arguments) { ProcessExpression(current, ref resultQuery); } } } } Damit haben wir unseren ersten lauffähigen Provider und können die Anwendung testen. October 14 ADC08 - LINQ TO …Silverlight 2.0 - RTWSilverlight 2.0 wurde heute fertiggestellt. Es enthält jedoch keine Änderungen zur RC0 Version und die Client-Runtime sollte automatisch ein Update erfahren. October 10 .net 4.0 & Visual Studio 2010LINQ Provider - Vom Ausdruck zum Ergebnis - Teil 3
Nachdem wir im Teil 2 unsere Query<T> Klasse implementiert haben stehen wir nun vor unserem letzten Problem: den eigentlichen Provider für die Datenquelle Dieser muss:
Genau dafür haben wir bereits vorab die Idee geboren eine entsprechende Provider-Basisklasse zu erstellen, um später nur noch die die eigentliche Logik - Provider.Execute(…) – umzusetzen zu müssen. Daher implementieren wir im Provider die Funktionalität um eine Instanz von Query<T> zu bilden und diese zu retournieren (CreateQuery<>()). public abstract class QueryProvider : IQueryProvider { #region IQueryProvider Members public IQueryable<T> CreateQuery<T>(Expression expression) { return new Query<T>(this, expression); } public IQueryable CreateQuery(Expression expression) { throw new NotImplementedException(); } T IQueryProvider.Execute<T>(Expression expression) { return (T)this.Execute(expression); } object IQueryProvider.Execute(Expression expression) { return this.Execute(expression); } #endregion public abstract object Execute(Expression expression); } In der Basisklasse erzeugen wir außerdem eine abstrakte Methode “Execute” die unser eigentlicher Provider später implementieren muss. public class MyCustomProvider : QueryProvider { public override object Execute(Expression expression) { //Execute Query, Create return Value(s) } } Im vierten Teil der Serie werden wir uns eine Linq.Abfrage bereit legen und die Execute Methode in unsere konkrete Providerklasse implementieren. October 09 DataBinding in WPF/Silverlight – Refresh ohne Code im UI - INotifyPropertyChanged
public class RefreshingClock : INotifyPropertyChanged { DispatcherTimer dt; public RefreshingClock() { dt = new DispatcherTimer(); dt.Interval = TimeSpan.FromSeconds(1); dt.Tick += dt_Tick; dt.Start(); } void dt_Tick(object sender, EventArgs e) { if (this.PropertyChanged != null) this.PropertyChanged(this, new PropertyChangedEventArgs("CurrentTime")); } public DateTime CurrentTime { get { return DateTime.Now; } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; #endregion } Hier ist eigentlich lediglich wichtig, dass wir immer, bei Änderungen d. Property “CurrentTime” unser INotifyPropertyChanged Event triggern müssen. <UserControl.Resources>
<local:RefreshingClock x:Key="Clock" />
</UserControl.Resources>
3) Das DataBinding: <TextBlock Text="{Binding Path=CurrentTime, Source={StaticResource Clock}}" />
Und somit haben wir 0 Zeilen Programmcode im eigentlichen UI. October 07 LINQ Provider - Vom Ausdruck zum Ergebnis - Teil 2
Zuerst beginnen wir nun die Funktionalitäten in Query<T> umzusetzen: public class Query<T> : IOrderedQueryable<T>, IQueryable, IOrderedQueryable { QueryProvider _Provider; Expression _Expression; public Query(QueryProvider provider) { this._Provider = provider; this._Expression = Expression.Constant(this); } public Query(QueryProvider provider, Expression expression) : this(provider) { this._Expression = expression; } //Implementierung der Interfaces ... } Bei der Implementierung des Interfaces machen wir nun nichts anderes als “jeweils” Provider.Execute(…) aufzurufen und diesen unsere Expression weitergereicht. public class Query<T> : IOrderedQueryable<T>, IQueryable, IOrderedQueryable { //... public IEnumerator<T> GetEnumerator() { var r = this.Provider.Execute<IEnumerable<T>>(this._Expression) as IEnumerable<T>; return r.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { var r = this.Provider.Execute(this._Expression) as IEnumerable; return r.GetEnumerator(); } //... } Und somit sind wir nun auch einem Geheimnis von LINQ auf die Schliche gekommen, weshalb Abfragen üblicherweise erst bei Zugriff ausgeführt werden. October 03 ADO.net DataServices
1) Erstellen einer neuen ASP.net Web Application 2) Ein ADO.net Entity Data Model erstellen (*.edmx) 3) Ein ADO.net Data Service hinzufügen und adaptieren. Imports System.Data.Services Imports System.Linq Imports System.ServiceModel.Web Public Class Northwind ' TODO: replace [[class name]] with your data class name Inherits DataService(Of NorthwindEntities) ' This method is called only once to initialize service-wide policies. Public Shared Sub InitializeService(ByVal config As IDataServiceConfiguration) ' TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc. ' Examples: ' config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead) ' config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All) config.SetEntitySetAccessRule("*", EntitySetRights.All) End Sub End Class Achtung das ADO.net DataService muss hierbei vom Context abgeleitet werden. 4) Testen des Services. –> F5 sollte hierfür reichen. Im einem zukünftigen Eintrag wollen wir das soeben erstellte Service noch konsumieren. Fragen dazu? Kommentar posten ;) September 30 Visual Studio 2010, .net Framework 4.0 |
|
|