domenica 21 dicembre 2008

Data Table "Inferenza" risolta

Tempo addietro avevo accennato al problema dell'infernza nell'atto di import di un file xml in una data table...

Il problema può essere risolto con molta semplicità il tutto dipende come sempre dalla situazione iniziale.

Caso 1






Field1Field2Field3
1LuendiMarzo
2MartediMarzo
3MercolediMarzo


Abbiamo eseguito DataTable.WriteXml(_FileName);
in _FileName troveremo il classico file Xml con il record di dichiarazione e i dati.

Conseiderati questi dati rileggendo i dati con DataTable.ReadXml(_FileName) non si verificheranno problemi di inferenza.

Caso 2






Field1Field2Field3
1Luendi
2Martedi
3MercolediMarzo


Abbiamo eseguito DataTable.WriteXml(_FileName);
in _FileName troveremo il classico file Xml con il record di dichiarazione e i dati.

Conseiderati questi dati rileggendo i dati con DataTable.ReadXml(_FileName) per la colonna field 3 potrebbero verificarsi problemi di infernza questo perchè solo un elemento (il 3) ha valorizzato correttamente il campo.

Se il file non è stato scritto da noi, l'unica è leggerlo prelevare per ogni nodo tutte le definizioni, e dichiarare tutte le colonne

for (int i =0 ; i < ColumnsReaded.Length-1 ; i++) { DataTable.Columns.Add(ColumnsReaded[i].ToString()); } DataTable.ReadXml(_FileName) ;

Tuttavia la soluzione migliore è evitarsi il problema alla radice....
DataTable.WriteXml(_FileName, XmlWriteMode.WriteSchema);
In questo modo qualunque sia lo schema della tabella verrà salvato nel file xml.

giovedì 18 dicembre 2008

DataTable non supporta l'inferenza di schema proveniente da Xml.

Che cosa vuol dire ?

più o meno il concetto è "la data table non riesce a capire che colonne dovrà creare al suo interno".

Questo problema si verifica quando stato leggendo un file xml generato o da una datatable o tipicamente errato.

Provate a verificare le colonne che state leggendo se per esempio per ogni row presente nel file c'e' lo stesso numero
di colonne. O se esiste nel file qualche carattere che non ci dovrebbe essere.

cerco una soluzione e la pubblico.. sempre che ci sia... !!

mercoledì 5 novembre 2008

Connettere un file mdf con c#

Più volte capita che si debba realizzare un applicazione che possa lavorare sia in modalità "alone" che in "in the net".

Questo potrebbe voler implicare che la nostra applicazione sappia scrivere e leggere su una o più fonte dati.
C'e' da dire che non sempre possiamo portarci dietro tutto un slq server e dobbiamo poter scegliere di puntare indipendentemente o al nostro Sql Express Edition, o ad un Sql Server nella nostra lan.

Da qui il dilemma. Come mi comporto nel disaccoppiamento fra Manager e Data Provider ?? mi scrivo due data provider uno per Sql Server e un per Sql Express ??
Ma no alla fine fanno le stesse cose girano le stesse query potrebbe non aver senso. (il problema al più nasce nella sincronizzazione).

Ed è quindi più che lecito pensare che c'e' un arcano per venirne a capo.

Un data provider semplice "dovrebbe" aver lo scopo di indicare ad un potenziale data Reader Dove effettuerà la lettura,
mi è lecito dertminare quindi a questo livello diversi tipi di stringhe di connessione..


E qui sorge il problema come mi connetto ??

la cosa è molto semplice basta creare una stringa di connessione secondo quanto segue ..

Data Source=.\SQLEXPRESS;
AttachDbFilename=[Nome file];
Integrated Security=True;
Connect Timeout=30;
User Instance=True

E fatte le dovute prove incontrerte un errore documentato da ms, ma momentaneamente
spostato nella TODO LIST!

http://support.microsoft.com/?scid=kb%3Ben-us%3B908038&x=13&y=16

La soluzione più rapida è verificare l'esistenza di questo percorso e sistemare il vostro mdf ( più ldf qui)

C:\Programmi\Microsoft SQL Server\MSSQL.1\MSSQL\Data

Inoltre è necessario che in nome file sia riportato tutto il percorso.. nella sua interezza più il nome del file.

Aspetteremo, magari se ne accorgono e correggono.. ma per la distribuzione ??
come si potrà fare ??

martedì 12 febbraio 2008

OnItemDataBound

Questo sconosciuto...

Un evento molto particolare che consente di ritoccare i dati in fase di Bound. Per comprendere con un po' più di chiarezza mi permetto di introdurre un esempio "classico".

Abbiamo una griglia, abbiamo degli elementi che popoleranno la griglia, tramite associazione DataSource.

La necessità e che l'utente finale possa eliminare i dati, rispondendo alla domanda "Ne sei davvero sicuro?".

Diciamo che nel novanta per cento dei casi l'utente non lo è, ed è per questo che si deve dare la possibilità di annullare
l'azione.

Immagino che tanti di voi abbiano provato in più di un occasione tentato di intromettersi nel sottile codice
di una grid view per poter operare una serie di aggiunte rischiando di rendere intricato il codice.

Una soluzione c'e', sfruttare l'evento di cui sopra.

Dopo aver associato i dati tramite
GridView.DataSource = [oggettoDati];
Si è soliti eseguire il
GridView.DataBind();
E' appunto in questa circostanza che si scatena l'evento

OnItemDataBound

Coinvolge tutti gli elementi presenti nella griglia, e naturalmente la griglia stessa.

protected void DataItemBound(object source, DataGridItemEventArgs e)
{
if ((e.Item.ItemType == ListItemType.Item) | (e.Item.ItemType == ListItemType.AlternatingItem))
{
LinkButton ln = (LinkButton)e.Item.Cells[5].Controls[0];
ln.Attributes.Add("onClick", "return(confirm('Sei sicuro di voler cancellare questo elemento?'))");
}
}




Il primo If (...) mi consente di lavorare esclusivamente sugli elementi (no su header, no su footer).

Nella mia gridview, nella colonna 5 ho un LinkButton che effettuerà la cancellazione dell'elemento
A detto controllo aggiungo un attributo "onClick" che verrà eseguito lato client.

Il valore dell'attributo non è altro che lo script che dovrà essere eseguito.

E' possibile applicare questa logica su tutti i controlli che naturalmente espongono OnItemDataBound o eventi simili che abbiano lo stesso comportamento.

Come è logico questo tipo di attività può notevolmente rallentare il render del controllo che stiamo utilizzando.
Ed è di conseguenza consigliato applicarlo ad un controllo che possa consentire la navigazione a pagine.

Nel mio caso mostro esclusivamente 15 elementi, è quindi comprensibile che questa struttura possa consentirmi una certa qualità.

lunedì 28 gennaio 2008

Modificatori di accesso

Public,Private,Sealed,Static...

Sono modificatori di accesso ossia sono dei delle parole private del linguaggio che indicano al compilatore il tipo di accesso che si avrà nei confronti di quella Classe, metodo, proprietà...

Benchè ci siano dei casi specifici dove utilizzare uno specifico modificatore i principali (giusto perchè sono i più utilizzati) rimangono Public e Private.

il loro scopo è quello di rendere Pubblico o Privato un metodo o una proprietà una classe

Questa rimarrà visibile a livello di soluzione
public class Tank
{
}
All'esterno sarà possibile individuare questa classe e usarla


Questa rimarrà visibile a livello di progetto (dato che private è di default nella dichiarazione di una classe lo si omette)
class Tank
{
}
Se la nostra soluzione fosse costituita da più progetti, questa classe da altri progetti non verrebbe vista.

Concettualmente è di fondamentale importanza compredere quanto un modificatore agisce su quanto abbiamo scritto.

public class Tank
{
private int _capacita;
public void Riempi(){...}
}

public class UsaTank
{
Tank t = new Tank();

public UsaTank() {t.Riempi();}
}

In questo specifico caso Tank e UsaTank sono due class dello stesso progetto.

In UsaTank sicuramente non avremmo accesso a _capacita perchè il suo modificatore rimane privato e non ne
consente quindi l'accesso dall'esterno.

Condividere.

In fase di progettazione, una delle parti più complesse, è sicuramente la condivisione delle informazioni.

E' possibile che membri dello stesso gruppo possano trovarsi nella spiacevole circostanza di avere informazioni diverse, sullo svolgimento del progetto.

E' sufficiente un piccolo problema a creare problemi relativamente grossi.

La base di questo rischio è la scarsità o l'inapropriata condivisione delle informazioni.

La Ide del frame work mette a disposizione svariate possibilità per realizzare frammenti di documentazione, e meglio ancora dispone di un tool dedicato completamente al diagramma delle classi.

/// <>
///
/// < /summary >
/// < name="obj"> < /param >

Questo tag si può (si deve/si dovrebbe) utilizzare, per dare una completa panoramica di quello quanto svolge il metodo.
Può essere esteso anche alle proprietà o agli eventi.

Ma ancora una volta è necessario che sia utilizzato con buon senso e cognizione di causa.


/// <>
/// Metodo WriteToPort Scarica il buffer sulla porta indicata dal parametro port
///< /summary >
///
/// < name="Port">Indirizzo logico della porta su cui scrivere< /param >


Questo "commento" risulta Leggibile e quanto meno comprensibile chiunque riesce a comprendere qual'e' lo scopo del metodo che sta per leggere.

Non da meno nel caso di utilizzo della class che espone questo metodo si avrebbe un tooltip recante la medesima descirzione.


/// <>
/// WriteToPort
/// Scrive dei bit nella port ( quando funziona !! )
/// < /summary >
/// < name="Port">< /param >


Naturalmente questo commento non è assolutamente valido, ne comprensibile. Ma il più delle volte ringrazio anche chi scrive commenti simili, perchè quanto meno ci sono.

E' valutabile il fatto che un commento sia efficace o meno, si deve comunque sensibilizzare il proprio team a creare
commenti OGGETTIVAMENTE comprensibili.

Un ulteriore strumento è la direttiva #region che permette di raggrupare delle righe di codice secondo una determinata logica.

#region Private
private int _id_CampoChiave;
private string _Campo_Nome;
private string _Campo_Note;
#endregion

In questo specifico caso è possibile indicare la presenza di una serie di attributi privati.

E' possibile specificare definizioni più o meno complesse, o annidare vari region fra loro.

Ancora una volta è necessario istruire il proprio gruppo in modo che vi sia uno standard diffuso e conosciuto, al fine
che tutti possano CONDIVIDERE la stessa esperienza.

mercoledì 9 gennaio 2008

Static

Che cos'e' una classe statica ?
Tecnicamente parlando una classe statica è una oggetto che espone i propri membri senza aver bisogno di essere istanziato.
Una classe dichiarata come static non potrà essere ereditata.

Quando ne è consigliato l'utilizzo ?
L'impiego di una classe statica è consigliato quando la classe non contiene dati, comportamenti che dipendono dalla classe stessa.

Come si dichiara una classe statica ?
public static class TestStatic
Questa scrittura implica che tutti i membri della classe dovranno essere dichiartati static.

esempio
class Program
{
static void Main(string[] args)
{
string content = "testo dimostrativo";

TestStatic.WriteFile(@"C:\test.txt", content, true);

content = TestStatic.ReadFile(@"C:\test.txt");
}

}

public static class TestStatic
{
public static string ReadFile(string fileName)
{
string dataFromFile ="";

// processo di verifica ( esistenza )

// processo di lettura

return dataFromFile;
}

public static void WriteFile(string fileName, string fileContent, bool Append)
{
// processo di verifica ( percorso )

// processo di verifica ( modalità di scrittura)

// processo di scrittura
}
}

Posto che vi sia del codice e posto anche che questa situazione abbia una certa utilità, abbiamo creato una
sottospecie di utility statica che legge e scrive un file.

Posto che si voglia aggiungere un contatore dei soli file creati :
public static class TestStatic
{
private static int fileCount = 0;

public static string ReadFile(string fileName)
{
string dataFromFile ="";

// processo di verifica ( esistenza )

// processo di lettura

return dataFromFile;
}

public static void WriteFile(string fileName, string fileContent, bool Append)
{
// processo di verifica ( percorso )

// processo di verifica ( modalità di scrittura)

if (Append == false)
{
// implica che stiamo creando un nuovo file...
fileCount++;
}

// processo di scrittura
}

public int FileCounter()
{
return fileCount;
}
}

Aggiungendo un metodo la cui firma non è statica il compilatore non consente la "compilazione"
comunicando che per una classe statica tutti i membri devo essere tali.

public static class TestStatic
{
private static int fileCount = 0;

public static string ReadFile(string fileName)
{
string dataFromFile ="";

// processo di verifica ( esistenza )

// processo di lettura

return dataFromFile;
}

public static void WriteFile(string fileName, string fileContent, bool Append)
{
// processo di verifica ( percorso )

// processo di verifica ( modalità di scrittura)

if (Append == false)
{
// implica che stiamo creando un nuovo file...
fileCount++;
}

// processo di scrittura
}

public static int FileCounter()
{
return fileCount;
}
}

Si possono creare Classi non statiche con metodi statici ?

Si si può fare e a questo punto solo i metodi di quella classe potranno essere utilizzati come static,
senza quindi dover istanziare la classe.

class Program
{
static void Main(string[] args)
{

TestStaticMethod ts = new TestStaticMethod();

Console.WriteLine(ts.GetTestResult());

Console.WriteLine(TestStaticMethod.GetStaticTestResult());

}

}

public class TestStaticMethod
{

public TestStaticMethod()
{
// costruttore
}

public static string GetStaticTestResult()
{
return "Risultato statico del test";
}

public string GetTestResult()
{
return "Risultato " + DateTime.Now.ToShortTimeString() + " non statico del test";
}
}

Differenze fra le due classi TestStatic e TestStaticMethod

//
// Questo non può essere fatto
// la classe TestStatic non è visibile
public class Test : TestStatic
{

}

//
// Questo è consentito
public class Test : TestStaticMethod
{

}

Ed è consentito anche questo ...
class Program
{
static void Main(string[] args)
{

Test nTest = new Test();

Console.WriteLine(nTest.GetTestResult());

Console.WriteLine(Test.GetStaticTestResult());
}
}

public class Test : TestStaticMethod
{

}