Entity Framework – Part 3

29 באוקטובר 2009

תגיות: , , ,
אין תגובות

 


בפרק הקודם הגענו למצב שיש לנו טבלה אחת שממופה לטבלה

ישות אחת

כהמאפיין InternalGender הוגדר כ – private והוספנו partial class כדי לחשוף אותו כ – enum

 



public enum UserGender


{


    Male,


    Female


}


 


public partial class User


{


    public UserGender Gender


    {


        get


        {


            return (UserGender)this.InternalGender;


        }


        set


        {


            InternalGender = (int)value;


        }


    }


}


 

 

נפתח את המודל בעזרת XmlEditor

 

 

Open With

 

 

Xml editor

 

 

מומלץ לסדר את ה – xml על ידי לחיצה על Format the whole document. (צירוף המקשים Ctrl+e+d)

 

לאחר מכן נלחץ קליק ימין בעכבר ונבחר ב – Outlining ואז ב- Toggle all outlining

 

 

outlining

 

 

כעת כל ה – xml יהיה מכווץ, נרחיב את ה – xml על ידי לחיצה על הסימן ה – + ונראה את החלק של ה – designer והחלק של ה – Runtime (כבר דברנו על זה קצת בפרק הראשון)

 

כשנרחיב את החלק של edmx:RunTime נראה את הקוד הבא

 

Model

 

 

כמו שכבר למדנו –

SSDL מתאר את את הסכמה של הנתונים (הסיבה שקוראים לזה SSDL כלומר – Store Schema Definition Language ולא DDSL כלומר Data Schema Definiton Language היא מכיון שכשפיתחו את Entity Framework הם חשבו על העתיד ולא כל מידע חייב להגיע מבסיס נתונים – ולכן הם קראו לזה Store (אולי זה יהיה xml או מקור נתונים אחר)

 

נפתח את ה – + של StorageModel, נגלה אלמנט שנקרא Schema – בברירת מחדל הוא נראה כך:

 



<Schema Namespace="EFLabModel.Store"


        Alias="Self"


        Provider="System.Data.SqlClient"


        ProviderManifestToken="2005"


        xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"


        xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">


 

 

תוכלו לקרוא כאן על כל האלמנטים של ה – Schema (אני גם ארחיב עליהם בעתיד)

 

אפשר לראות את הסכמה של הסכמה – כלומר איזה אלמנטים יכולים להיות בחלק של ה – SSDL בנתיב הבא:

C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas\System.Data.Resources.SSDLSchema.xsd

 

מעבר זריז:

Namespace: בדרך כלל השם של בסיס הנתונים בתוספת השם Store לאחר מכן במיפוי צריך את ה – namespace כדי להגיע לאלמנטים הפנימיים שהוגדרו במודל

Alias: כברירת מחדל Self – די ברור, במקום לכתוב בכל מקום (בחלק של ה – SSDL) את ה – namespace ניתן להתייחס ל – Alias לדוגמא: נוכל לכתוב

 



<EntitySet Name="User" EntityType="EFLabModel.Store.User" store:Type="Tables" Schema="dbo" />


או שנוכל לכתוב



<EntitySet Name="User" EntityType="Self.User" store:Type="Tables" Schema="dbo" />


 

שימו לב להתייחסות במאפיין EntityType.

 

Provider: מגדיר מיהו ספק הנתונים שלנו כמובן שזה לא חייב להיות SqlServer וזה יכול להיות גם Oracle ועוד הרבה אחרים (אין ספק נתונים ל – Access) למידע על Providers

 

ProviderManifestToken: מגדיר את הגרסה של בסיס הנתונים כך שתרגום הקוד לשאילתות SQL יתורגמו כמו שצריך.

 

 

בתוך האלמנט Schema נראה שני אלמנטים: הראשון EntityContainer נראה כך:

 



<EntityContainer Name="EFLabModelStoreContainer">


  <EntitySet Name="User" EntityType="EFLabModel.Store.User" store:Type="Tables" Schema="dbo" />


</EntityContainer>


 

ה – EntityContainer מאגד טבלאות וקשרים – כלומר כשיהיו לנו טבלאות עם קשרים ביניהם אנחנו נראה  ליד האלמנט EntitySet גם אלמנטים מסוג AssociationSet שמגדירים קשרים (בפרקים הבאים).

לאלמנט EntityContainer יש מאפיין Name שמזהה אותו. כך שנוכל למפות אותו לישות במודל שלנו.

 

ה – EntitySet מתאר טבלה אחת (או View) בבסיס הנתונים (הוא לא ממש מתאר את הטבלה זה תפקידו של ה – EntityType – יותר נכון להגיד שהוא מגדיר את הטבלה ומקשר אליה טבלאות אחרות אם צריך) יש לו את המאפיינים Name (שבדרך כלל יהיה השם של הטבלה) EntityType (שמיד נראה כיצד הוא מתאר לפרטי פרטים את הטבלה) ומגדיר את סוג ה – EntityType (האם זה טבלה או View).

 

אחד הסיבות שאי אפשר היה להסתפק רק ב – EntityType וצריך גם את ה – EntitySet היא כדי שיהיה היכן להגדיר שאילתות כלומר – במידה ונרצה להוסיף למודל שאילתה ישירה מול בסיס הנתונים נוכל להוסיך אותה בתוך ה – EntitySet (זהו נושא מתקדם ונראה את זה בפרקים הבאים), וכמובן גם עבור ירושות.

 

תחת ה – EntitySet נראה את אלמנט EntityType

 



<EntityType Name="User">


  <Key>


    <PropertyRef Name="Id" />


  </Key>


  <Property Name="Id" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />


  <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />


  <Property Name="PenName" Type="nvarchar" MaxLength="50" />


  <Property Name="Picture" Type="image" />


  <Property Name="Email" Type="varchar" Nullable="false" MaxLength="50" />


  <Property Name="Gender" Type="int" Nullable="false" />


</EntityType>


 

מתאר בצורה הכי פשוטה את מבנה הטבלה יש לו את ה – Name (שהוא שם הטבלה בבסיס הנתונים) יש את אלמנט ה – key שממופה לאחד מהעמודות בטבלה ויש תיאור של כל שאר העמודות.

 

 

 

כעת נעבור לחלק השני של ה – xml ה – CSDL (שמתאר את מבנה הישות)

כשנרחיב את ה -edmx:ConceptualModels נראה את האלמנט Schema



<Schema Namespace="EFLabModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">


 

יש לו את המאפיינים של ה – namespace וה – alias שהמשמעות שלהם היא כמו ב – SSDL.

 

בתוך האלמנט נמצא את שני האלמנטים הבאים, הראשון:

 

EntityContainer שמכיל את כל ה – EntitySet שמתארות את הישויות ואת הקשרים ביניהם

כמובן שבתוך ה – EntityContainer נמצא את כל ה – AssociationSet שמתארים את הקשרים בין הישויות (בפרקים הבאים)



<EntityContainer Name="EFLabEntities1">


 בתוך ה – EntityContiner נמצא את ה – EntitySet

 



<EntitySet Name="User" EntityType="EFLabModel.User" />


 

אחד הסיבות שצריך EntitySet ולא מספיק EntityType היא עבור ירושות – כלומר אם יש לנו שני EntityType שיורשים אחד מהשני שניהם יהיו בתוך אותו EntitySet (נראה בפרקים הבאים)

 

 

בתוך ה – Schema EntityContainer יש גם את ה – EntityType



<EntityType Name="User">


  <Key>


    <PropertyRef Name="Id" />


  </Key>


  <Property Name="Id" Type="Int64" Nullable="false" />


  <Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true"


            FixedLength="false" />


  <Property Name="PenName" Type="String" MaxLength="50" Unicode="true"


            FixedLength="false" />


  <Property Name="Picture" Type="Binary" MaxLength="Max" FixedLength="false" />


  <Property Name="Email" Type="String" Nullable="false" MaxLength="50" Unicode="false"


            FixedLength="false" />


  <Property Name="InternalGender" Type="Int32" Nullable="false"


            a:GetterAccess="Private"


            a:SetterAccess="Private"


            xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />


</EntityType>


 

הוא מתאר בצורה פשוטה את הישות – שימו לב למאפיין InternlGender שיש לו את ההגדרה private עבור ה – Getter וה – Setter, יש לו כמובן עוד הרבה מאפיינים ואלמנטים שנדבר עליהם בפרקים הבאים.

 

 

 

 

כעת נעבור לחלק האחרון של ה – xml שהוא המיפוי בין ה – SSDL להין ה – CSDL

כדי שלא תצטרכו לדלג בפוסט כדי לחפש את על מה אני מדבר – אני אציג כאן את שני חלקי ה – xml במלואם

 



<!– SSDL content –>


<edmx:StorageModels>


  <Schema Namespace="EFLabModel.Store"


          Alias="Self"


          Provider="System.Data.SqlClient"


          ProviderManifestToken="2005"


          xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator"


          xmlns="http://schemas.microsoft.com/ado/2006/04/edm/ssdl">


    <EntityContainer Name="EFLabModelStoreContainer">


      <EntitySet Name="User" EntityType="EFLabModel.Store.User" store:Type="Tables" Schema="dbo" />


 


    </EntityContainer>


    <EntityType Name="User">


      <Key>


        <PropertyRef Name="Id" />


      </Key>


      <Property Name="Id" Type="bigint" Nullable="false" StoreGeneratedPattern="Identity" />


      <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />


      <Property Name="PenName" Type="nvarchar" MaxLength="50" />


      <Property Name="Picture" Type="image" />


      <Property Name="Email" Type="varchar" Nullable="false" MaxLength="50" />


      <Property Name="Gender" Type="int" Nullable="false" />


    </EntityType>


  </Schema>


</edmx:StorageModels>


<!– CSDL content –>


<edmx:ConceptualModels>


  <Schema Namespace="EFLabModel" Alias="Self" xmlns="http://schemas.microsoft.com/ado/2006/04/edm">


    <EntityContainer Name="EFLabEntities1">


      <EntitySet Name="User" EntityType="EFLabModel.User" />


    </EntityContainer>


    <EntityType Name="User">


      <Key>


        <PropertyRef Name="Id" />


      </Key>


      <Property Name="Id" Type="Int64" Nullable="false" />


      <Property Name="Name" Type="String" Nullable="false" MaxLength="50" Unicode="true"


                FixedLength="false" />


      <Property Name="PenName" Type="String" MaxLength="50" Unicode="true"


                FixedLength="false" />


      <Property Name="Picture" Type="Binary" MaxLength="Max" FixedLength="false" />


      <Property Name="Email" Type="String" Nullable="false" MaxLength="50" Unicode="false"


                FixedLength="false" />


      <Property Name="InternalGender" Type="Int32" Nullable="false"


                a:GetterAccess="Private"


                a:SetterAccess="Private"


                xmlns:a="http://schemas.microsoft.com/ado/2006/04/codegeneration" />


    </EntityType>


  </Schema>


</edmx:ConceptualModels>


 

 

כעת נרחיב את האלמנט edmx:Mappings ונראה את ה – xml הבא:

 

 




<edmx:Mappings>


  <Mapping Space="C-S" xmlns="urn:schemas-microsoft-com:windows:storage:mapping:CS">


    <EntityContainerMapping StorageEntityContainer="EFLabModelStoreContainer"


                            CdmEntityContainer="EFLabEntities1">


      <EntitySetMapping Name="User">


        <EntityTypeMapping TypeName="IsTypeOf(EFLabModel.User)">


          <MappingFragment StoreEntitySet="User">


            <ScalarProperty Name="Id" ColumnName="Id" />


            <ScalarProperty Name="Name" ColumnName="Name" />


            <ScalarProperty Name="PenName" ColumnName="PenName" />


            <ScalarProperty Name="Picture" ColumnName="Picture" />


            <ScalarProperty Name="Email" ColumnName="Email" />


            <ScalarProperty Name="InternalGender" ColumnName="Gender" />


          </MappingFragment>


        </EntityTypeMapping>


      </EntitySetMapping>


    </EntityContainerMapping>


  </Mapping>


</edmx:Mappings>


 

 

האלמנט הראשון שנמצא הוא Mapping הוא האלמנט שמכיל את כל מה שקשור למיפוי, המאפיין Space אין לו משמעות מיוחדת הוא תמיד יהיה C-S כלומר ה – C של CSDL וה – S של SSDL

 

בתוכו יש לנו את ה – EntityContainerNapping  שני המאפיינים שלו מקשרים בין ה – EntityContainer של ה – CSDL לבין ה – EntityContainer של ה – SSDL

בנוסף אנחנו נראה בפרקים הבאים איך נקשר בין  stored procedure  לבין פונקציה שהוגדרה במודל הישויות.

 

 

בתוך ה – EntityContainerMapping יש לנו את ה – EntitySetMapping שממפה בין ה – EntitySet של ה – SSDL לבין המקביל שלו ב – CSDL.

 

EntityTypeMapping ממפים בין ה – EntityTypes של ה – CSDL וה – SSDL המאפיין TypeName היה יכול להיכתב גם בצורה הזאת



<EntityTypeMapping TypeName="EFLabModel.User">


הסיבה לשימוש ב – IsTypeOf היא כשאנחנו עובדים עם ירושה והאובייקט שממופה יכול לרשת מ – User (בפרקים הבאים ארחיב על הנושא)

 

האלמנט MappingFragment אין לו משמעות כרגע אבל יהיה לו משמעות בישויות המורכבות מכמה טבלאות – כלומר אם תבנו ישות שהמאפיינים שלהם מגיעים מכמה טבלאות (נקרא Entity Spliting) יהיה משמעות לאלמנט הזה

 

בתוכו יש מיפוי רגיל של מאפיין לעמודה.

 

 

בפרק הבא אנחנו נראה מה התרחש מאחורי הקלעים של הקוד המחולל בצורה אוטומטית ולאחר מכן נוכל להמשיך לבנות את המודל שלנו.

 

 

דברים שהזכרתי שנלמד בהמשך:

על כל האלמנטים של ה – Schema .

על קשרים בין ישויות.

על ירושה של ישויות.

הגדרת פונקציות למודל.

מאפיינים של EntityType.

 

 

ותודה לעידו על התמיכה

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *