Zum Inhalt, überspringe Kopfzeile Zum Navigation, überspringe Kopfzeile
Wer die Methode FindAll() des DirectorySearcher-Objektes benutzt hat, wird bestimmt schon, je nach LDAP-Filter, festgestellt haben das nur maximal 1000 gefundene Objekte zurückgeliefert werden. Das liegt daran das in den Einstellungen des ADS diese Grenze festgelegt ist. In der Standardeinstellung, wenn man nichts auf dem Server geändert hat, steht der Wert auf 1000.
Was tun wenn man nun aber mehr als 1000 Objekte abfragen sollte?
Schnell fällt der Blick auf die Eigenschaft SizeLimit des DirectorySearcher-Objektes. Setzt man diesen Wert aber auf z.B. 2000 so bekommt man dennoch nur 1000 Objekte mit FindAll() zurückgeliefert. Man kann mit SizeLimit die Anzahl der Objekte nach unten begrenzen, aber nicht über die Server-Grenze hinausgehen.
Die korrekte Lösung findet man in der Eigenschaft PageSize des DirectorySearcher-Objektes. Hat man diesen Wert nicht geändert, so steht er auf 0. Dies bedeutet das maximal die besagten 1000 Objekte – also die Server-Grenze – abgefragt werden.
searcher.PageSize = 2000
Erhöht man nun den Wert auf 2000 so wird man feststellen das man immer noch 1000 Objekte mit FindAll() geliefert bekommt. Eine Erhöhung des Wertes von PageSize über die Server-Grenze ist nicht möglich bzw. erlaubt. Der ADS ignoriert den Wert dann einfach.
searcher.PageSize = 1000
Setzt man den Wert auf 1000, also auf die Grenze die im ADS eingestellt ist, so erhält man mit FindAll() auch mehr als 1000 Objekte. Die Abfrage erfolgt nun Seitenweise im Hintergrund an die ADS. Hat man PageSize gesetzt, so sollte man das DirectorySearcher-Objekt via Dispose() nach der Benutzung aufräumen.
try {
searcher = new DirectorySearcher();
searcher.PageSize = 1000;
// Weitere Einstellungen für searcher
results = searcher.FindAll();
// Ergebnis bearbeiten
} catch {
throw;
}
finally {
if (searcher != null) searcher.Dispose();
if (results != null) results.Dispose();
}
Geschrieben von Stefan Jahn
in C-Sharp
um
16:16
| Kommentare (0)
| Trackbacks (0)
Wenn man Tabellen mit Daten aus einer Datenbank füllt ist die Sortierung eigentlich kein Problem. Man gestaltet entsprechend die Datenbankabfrage (SQL) und sortiert die Datensätze schon beim Einlesen der Daten.
Was ist aber wenn man die Datensätze schon in einer DataTable vorliegen hat, z.B. bei einer manuell gefüllten Tabelle, und diese nun sortieren will? Die Klasse DataTable selber stellt keine Funktion zur Sortierung zur Verfügung.
Man kann den Umweg über ein DataView nehmen. Ein DataView kann man nach jeder beliebigen Spalte sortieren lassen.
DataView view = new DataView( table ); view.Sort = "[Spaltenname]"; table = view.ToTable();
Beispiel:
DataTable table = new DataTable();
table.Columns.Add( new DataColumn( "Nachname", typeof( string )));
table.Columns.Add( new DataColumn( "Vorname", typeof( string )));
table.Rows.Add( new object[] { "de Burgh", "Chris" } );
table.Rows.Add( new object[] { "Minogue", "Kylie" } );
table.Rows.Add( new object[] { "Oldfield", "Mike" } );
table.Rows.Add( new object[] { "Brightman", "Sarah" } );
DataView view = new DataView( table );
view.Sort = "Nachname";
table = view.ToTable();
Als Werte für den Property Sort kann man auch mehere Spalten oder sogar die Sortierrichtung angeben, so wie man es vom Sort-Syntax bei SQL gewohnt ist:
view.Sort = "Nachname, Vorname"; view.Sort = "Nachname DESC"; view.Sort = "Nachname DESC, Vorname";
Geschrieben von Stefan Jahn in C-Sharp um 21:01 | Kommentare (0) | Trackbacks (0)
Je nach Art des Programmes ist es unerwünscht bzw. kann sogar zu Fehlern oder Nebenwirkungen führen wenn man dieses mehrmals startet. Wie aber nun herausfinden ob das eigene Programm schon läuft?
Dafür kann man sich die Mutex-Klasse aus System.Threading zu nutze machen.
using System;
using System.Threading;
class Program
{
private static Mutex mutex;
public static void Main( string[] args )
{
// Falls Programm schon laeuft neuen Start verhindern.
if ( IsRunning() ) return;
Console.WriteLine( "Hello World" );
Console.ReadLine();
}
/// <summary>
/// Pruefen ob Programm schon laueft.
/// </summary>
/// <returns>True = Programm laeuft schon</returns>
public static bool IsRunning() {
// Eindeutige Programmkennung erzeugen
mutex = new Mutex( false, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name+"_MultiStartPrevent" );
if ( mutex.WaitOne( 0, true ) ) return false;
return true;
}
}
Geschrieben von Stefan Jahn
in C-Sharp
um
20:29
| Kommentare (0)
| Trackbacks (0)
Seit C# 3.0 kann man ja via LINQ eine Datenbank abfragen. Eine schöne Sache. Ab und zu, für bestimmte Zwecke, benötigt man aber immer noch die Ergebnisse als klassische DataTable. Wie wandelt man nun das Ergebnis einer LINQ-Abfrage in eine DataTable um?
Hier die LINQ-Abfrage die mir mein Adressbuch ausliest:
DataContext context = new DataContext();
var query = from s in context.Personen
orderby s.Nachname
select s;
Die Datensätze hat man nun in query. Man könnte jetzt nun mit foreach jeden einzelnen Datensatz abfragen und in eine DataTable ablegen. Es geht aber noch etwas einfacher:
using System;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
/// <summary>
/// Ergebnis einer LINQ-Abfrage in eine DataTable umwandeln.
/// </summary>
/// <param name="query">Abfrageergebnis</param>
/// <param name="context">Context</param>
/// <returns>Tabelle</returns>
public DataTable ConvertLinqToDatatable( IQueryable query, DataContext context )
{
DataTable table = null;
IDbCommand cmd = null;
SqlDataAdapter adapter = null;
try
{
// LINQ-Abfrage in Tabelle speichern
cmd = context.GetCommand( query );
adapter = new SqlDataAdapter();
adapter.SelectCommand = (SqlCommand)cmd;
table = new DataTable();
cmd.Connection.Open();
adapter.FillSchema( table, SchemaType.Source );
adapter.Fill( table );
return table;
}
catch
{
throw;
}
finally
{
if ( table != null ) table.Dispose();
if ( adapter != null ) adapter.Dispose();
if ( cmd != null )
{
cmd.Connection.Close();
cmd.Dispose();
}
}
}
Somit einfach wie gewohnt eine LINQ-Abfrage durchführen und dann das Ergbnis mit der Funktion ConvertLinqToDatatable() umwandeln lassen:
DataContext context = new DataContext();
var query = from s in context.Personen
orderby s.Nachname
select s;
DataTable = ConvertLinqToDatatable( query, context );
Geschrieben von Stefan Jahn
in C-Sharp
um
22:23
| Kommentare (0)
| Trackbacks (0)
Zum Inhalt zurück, überspringe Navigation | Zum Seitenanfang