Supponiamo di avere un data model basato su LINQ to SQL e avere la necessità, per qualche motivo, di operare sul campo che ne rappresenta la Primary Key.
Un modo utile per ottenere questo campo è quello di ricorrere alla Reflection in modo da recuperarne la PropertyInfo.
Conoscendo alcune caratteristiche della entity che stiamo esaminando, e controllando se la classe in oggetto è decorata con un attributo di tipo System.Data.Linq.Mapping.ColumnAttribute possiamo facilmente riuscire nel nostro scopo.
Creiamo quindi una classe statica per contenere i metodi che implementeremo come extension method della classe System.Type:
... using System.Collections.Generic; using System.Reflection; using System.Data.Linq.Mapping; ... namespace MyNamespace { public static class ExtensionMethods { // my extension methods goes here } }
In questa classe andremo a definire i metodi che ci servono per lo scopo. Come detto si tratta di extension methods, che in pratica rappresentano delle estensioni a delle classi già esistenti.
Il primo extension methods che implementeremo sarà appunto quello per verificare se esiste e quale sia la property che identifica la primary key:
public static PropertyInfo GetPrimaryKey(this Type TEntity) { PropertyInfo piReturn = null; // verifico che il tipo sia un generico e prendo sempre il tipo del primo argomento Type TTEntity = (TEntity.IsGenericType) ? TTEntity = TEntity.GetGenericArguments()[0] : null; if (TTEntity != null) { foreach (PropertyInfo pi in TTEntity.GetProperties()) { // cerco tra le varie proprietà della entity, quella che è decorata // con ColumnAttribute e questi a sua volta indica che il campo rappresenta // una primary key if (pi.GetCustomAttributes(false) .Where(att => (att is ColumnAttribute)) .Where(att => ((ColumnAttribute)att).IsPrimaryKey) .Count() == 1 ) { // trovata la primary key piReturn = pi; break; } } } return piReturn; }
Un altro metodo utile, potrebbe essere quello per capire se una primary key è anche una identity. Per questo scopo, implementiamo il secondo extension method, che stavolta estende direttamente una PropertyInfo:
public static bool IsIdentity(this PropertyInfo pi) { bool bIsIdentity = (pi.GetCustomAttributes(false) .Where(att => (att is ColumnAttribute)) .Where(att => ((ColumnAttribute)att).DbType .ToString().ToUpper().Contains("IDENTITY")) .Count() == 1); return bIsIdentity; }
Per la nostra demo, utilizzeremo un database molto semplice in cui sono presenti solo tre tabelle, da cui otteniamo il seguente data model:
A questo punto, utilizzando sempre per la demo una console application, possiamo scrivere:
static void Main(string[] args) { MyDataContext ctx = new MyDataContext(); PropertyInfo pi1 = ctx.TableWithoutPrimaryKeys.GetType().GetPrimaryKey(); PropertyInfo pi2 = ctx.TableWithPrimaryKeys.GetType().GetPrimaryKey(); PropertyInfo pi3 = ctx.TableWithPrimaryKeyIdentities.GetType().GetPrimaryKey(); string sFormat = "Entity={0}, PrimaryKey={1}, Identity={2}"; string s1 = string.Format(sFormat, "TableWithoutPrimaryKeys", ((pi1 != null) ? pi1.Name : "no primary key"), ((pi1 != null) ? pi1.IsIdentity().ToString() : "no identity")); string s2 = string.Format(sFormat, "TableWithPrimaryKeys", ((pi2 != null) ? pi2.Name : "no primary key"), ((pi2 != null) ? pi2.IsIdentity().ToString() : "no identity")); string s3 = string.Format(sFormat, "TableWithPrimaryKeyIdentities", ((pi3 != null) ? pi3.Name : "no primary key"), ((pi3 != null) ? pi3.IsIdentity().ToString() : "no identity")); Console.WriteLine(s1); Console.WriteLine(s2); Console.WriteLine(s3); Console.ReadLine(); }
Il nostro output sarà il seguente:
Commenti
Per inserire un commento, devi avere un account.
Fai il login e torna a questa pagina, oppure registrati alla nostra community.