DCSIMG
DataReader Helper Part 2 - שלמה גולדברג (הרב דוטנט)

שלמה גולדברג (הרב דוטנט)

מרצה בסלע ויועץ בעולם ה - net.

DataReader Helper Part 2

 

בהמשך לפוסט הקודם שכתבתי על איך להביא נתונים מטבלה שממופה לאוביקט (אחד לאחד - עבור כל עמודה יש מאפיין עם אותו שם).
 
אז כמו שכתב רותם, ברגע שזה לא בדיוק אחד לאחד, זה לא יעבוד.
 
אז הנה הגירסא המורחבת של הפיתרון, (אפשר להוריד אותו מכאן.) (אולי כדאי להעלות אותו גם ל Code Plex, מה אתם אומרים ?)
 
וכמובן על ידי attribute,
 
ואם כבר הרחבתי את הפיתרון, אז שיניתי את המתודה ל Extension.
 
 
הנה הקוד של ה attribute:
 

[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]

public class MapAttribute : Attribute

{

    public string DatabaseColumn { get; set; }

    public bool UseMap { get; set; }

 

    public MapAttribute()

    {

        UseMap = true;

    }

}

 
יש לנו שני מאפיינים,
הראשון מחזיק את שם העמודה ב DB,
השני אומר האם להשתמש בעמודה הזאת (כי יתכן שיש לנו מאפיינים שהערך לא מגיע מה DB)
 
 
כך נראה האובייקט שלי:
 

public class Courses

{

    public int Id { get; set; }

 

    public string Name { get; set; }

 

    [Map(DatabaseColumn = "You")]

    public bool? IsActive { get; set; }

 

    [Map(UseMap = false)]

    public double Age { get; set; }

}

 
לא חייבים להשתמש ב attribute,
 
במידה ואנחנו לא רוצים שעמודה מסויימת תמופה, או שאנחנו רוצים למפות עם שם אחר
נוכל להשתמש עם ה attribute.
 
 
והנה הקוד המעודכן של המתודה: (שימו לב זה הפך ל Extension)
 

public static object Build(this DbDataReader reader, Type type)

{

    ConstructorInfo ctor = type.GetConstructor(Type.EmptyTypes);

    if (ctor == null)

    {

        throw new Exception(@"To use reader helper,

                              your class must have a

                              parameterless constructor");

    }

 

    object newObject = ctor.Invoke(null);

 

    PropertyInfo[] properties = type.GetProperties();

    foreach (var prop in properties)

    {

        string readerPropName = prop.Name;

 

        object[] maps = prop.GetCustomAttributes(typeof(MapAttribute), false);

        if (maps.Length == 1)

        {

            MapAttribute map = (MapAttribute)maps[0];

            if (!map.UseMap)

            {

                continue;

            }

 

            if (!string.IsNullOrEmpty(map.DatabaseColumn))

            {

                readerPropName = map.DatabaseColumn;

            }

        }

 

        object value = reader[readerPropName];

        if (value is DBNull)

        {

            prop.SetValue(newObject, null, null);

        }

        else

        {

            prop.SetValue(newObject, value, null);

        }

    }

 

    return newObject;

}

 
וההסבר:
 
נקבל את ה ctro,
נבדוק שיש אחד כזה ללא פרמטרים.
 
נייצר מופע שלו.
 
ונרוץ בלולאה על כל המאפיינים, עד כאן כמו בגירסה הקודמת.
 
נבדוק האם יש attribute מסוג MapAttribute
 
במידה וכן, והמאפיין UseMap הוגדר כ false, נתעלם מהמאפיין הזה
 
במידה ויש ערך במאפיין DatabaseColumn, נקח את ערכו.
 
וכעת זה ממשיך כמו בגירסה הקודמת, לוקח את הערך ומשים אותו בתוך המאפיין.
 
 
 
וכך נראה הקוד שמשתמש בו:
 

while (reader.Read())

{

    reqs.Add((Courses)reader.Build(typeof(Courses)));

}

תוכן התגובה

Rotem Bloom כתב/ה:

הבעיה היחידה שלי עם REFLECTION זה ביצועים.

הייתי ממליץ לך לבדוק את הביצועים של התשתית הזאת ככה סתם לסקרנות לדעת כמה זמן היא גוזלת לך.

כמובן שזה קריטי אם אתה משתמש בתשתית הרבה פעמים בצורה מרובה.

ביי רתם

# April 16, 2009 11:07 PM

Shlomo כתב/ה:

אני אבדוק,

בכל מקרה אני חושב שכל התשתיות עושות משהו דומה.

# April 17, 2009 7:11 AM

Arielr כתב/ה:

בוודאי שלא. תשתיות אחרות משתמשות ב-code generation או mail generation כדי ליצור את הקוד שממלא אובייקטים.

אורן עיני כותב עכשיו סדרה טובה של מאמרים על NHibernate בבלוג שלו. שווה קריאה.

# April 17, 2009 1:19 PM

Shlomo כתב/ה:

יכול להיות, בכל מקרה לא באתי להחליף תשתיות, זה רק במקרה שאנחנו לא רוצים להטמיע תשתיות שלמות ואנחנו רוצים לעבוד עם ado הפשוט, זה יכול להקל

# April 17, 2009 1:37 PM

Avi Pinto כתב/ה:

פוסט מעניין, ולאחר השינוי האחרון - גם יכול להיות לי שימושי מאד.

מצטרף לחשש של רתם, למרות ש asp.net מלאה ב reflection, הייתי עושה קצת בדיקות להשוואה

# April 17, 2009 4:14 PM
שלח תגובה

(שדה חובה)  

(שדה חובה)  

(אופציונלי)

(שדה חובה) 

Please add 5 and 7 and type the answer here:


Enter the numbers above: