martedì 3 marzo 2009

Add per la IDE 2005....

Siamo sicuri che funziona tutto ma proprio tutto ??

Provate a fare questo Esperimento.

Create un AddIn (fra i progetti dell'IDE o Extensibility)
Datagli come nome My.Addin
Selezionate le opzioni per:
  • Aggiungere l'addin al menu Tools
  • Aggiungere l'addin all'avvio
Ora lanciate il vostro spelndido programma e sorpresa non carica nulla.

Due appunti di viaggio ...
Il primo vi viene recapitata un' eccezione, ma molto forviante
ARGUMENT EXCEPTION e la prima cosa a cui si può pensare e che per un motivo o per l'altro non sia avvenuto il
caricamento del nuovo "comando"

La seconda e che spulciando fra glie elementi nella firma si scopre che
_addInInstance ... ha generato un eccezione ( differente dalla precedente... )

Nel dubbio dopo "parecchie parole offensive nei confronti dell'ide" scopro che ... l'addin c'e' è caricandolo non va lo stesso !!

Il problema è il "." ossia aggiungendo il punto il compilatore va a cercare una libreria che per lui non esiste..

Ci sarà un sistema per risolvere questo "possibile" baco ??

si semplice siate disordinati .. mettete pure dei nomi a caso .. e probabilmente il vostro add in andrà !

lunedì 2 marzo 2009

Campi di una tabella .. tipo ... e chiave primaria.

Come posso ottenere tutti i campi di una tabella con l'evidenza del campo chiave?

A molti di noi sarà capitato in più di un occasione la necessità di individuare tutti i campi di una tabella, un po per creare uno statement in automatico, un po' per analisi di Db che non abbiamo disegnato noi.

Nel mio caso sto realizzando un piccolo prodotto che crea soluzioni a pacchetto partendo da un db è va tutto bene fino a che non si impatta con le Query.. e non tanto con le SELECT .. ma con le UPDATE o con le DELETE.

Mi sono quindi domandato fino a che punto spingermi nell'implementazione... arrivando alla soluzione, che
"IO PREMO UN TASTO... LUI FA' IL 90% DEL COMPITO".

Quindi torniamo a bomba sulla query , ci servono:
  1. INFORMATION_SCHEMA.COLUMNS
  2. INFORMATION_SCHEMA.TABLE_CONSTRAINTS
  3. INFORMATION_SCHEMA.KEY_COLUMN_USAGE
La prima contiene i nomi delle colonne..
la seconda contiene i nomi delle constraint..
la terza (a me sembra una estensione della seconda)

Dalla prima recuperiamo le colonne contenenti Nome e Tipo
Dalla seconda e dalla terza recuperiamo se è un identity
Ma chiaramente mettendole in Join .. ci perdiamo tutti i campi che non lo sono ..
Quindi ci basta fare una piccola Union con gli SCARTATI...

ed ecco che cosa ne viene fuori ..

select
m.column_name,
m.data_type,
x.CONSTRAINT_TYPE
from
INFORMATION_SCHEMA.COLUMNS m,
(select
CONSTRAINT_TYPE,column_name
from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS a,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE b
where
a.table_name = '[tbName]'
and
b.CONSTRAINT_NAME = a.CONSTRAINT_NAME) AS x
where
m.table_name = '[tbName]'
and
x.column_name = m.column_name
UNION
select
m.column_name,
m.data_type,
' '
from
INFORMATION_SCHEMA.COLUMNS m,
(select
CONSTRAINT_TYPE,column_name
from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS a,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE b
where
a.table_name = '[tbName]'
and
b.CONSTRAINT_NAME = a.CONSTRAINT_NAME) AS x
where
m.table_name = '[tbName]'
and
x.column_name <> m.column_name


Provare per credere...


Questà può essere eseguita come sqlCommand da un qualsiasi dataAdapter ed il contenuto può agevolmente essere messo
in una dataTable..

Bhe buon divertimento

mercoledì 18 febbraio 2009

Thema e Custom Web Control.

Vi sarà captitato di affrontare il traumatico discroso di associare un tema ad un castom web control... si tratta di un qualcosa di assurdo e decisamente complesso soprattutto dal punto di vista della comprensione.

Poniamo l'esempio:

public class bPanel : Panel
{
public ovveride SkinID
{get{return base.SkinId;} set {base.SkinId = value;}}

public ovveride CssClass
{get{return base.CssClass;} set {base.CssClass = value;}}

protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
}
}


Non c'e' che dire non si tratta di una gran classe, ma questo è quanto basta
implementare per il nostro esempio.

Nella vostra pagina.. serve

<%@ Register Assembly="Miei.UI.WebControls" Namespace="Miei.UI.WebControls" TagPrefix="cc1" %>

e naturalmente

< id="bPanel1" runat="server" skinid="bPanel1">


Ora spostiamoci nel file del tema ...

MioTema.skin
e ri registriamo il controllo

<%@ Register Assembly="Miei.UI.WebControls" Namespace="Miei.UI.WebControls" TagPrefix="cc1" %>



< id="bPanel1" runat="server" skinid="bPanel1">



ed ora skinniamo come più ci piace..


< skinid="bPanel1" cssclass="laClasse" runat="server" backimageurl="img/MioSfondo.jpg" height="21px" width="100%">



sul web non c'e' scritto molto a riguardo, spero quindi che possa essere utile

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à.