Alper Konuralp

Kartınızı Oluşturun
Google+
Follow @alperkonuralp

Archive for the ‘Ado.Net’ Category

Entity Framework 4.1 Code First ile Ağaç Yapısındaki Tablolar

Entity Framework 4.1 Code First mimarisini kullanırken çalıştığınız projede karşınıza ağaç yapısında bir elemana ihtiyacı doğmuş olabilir. Ki benim başıma böyle bir durum geldi. Normal yollarla bu problemi çözmeye çalıştığınızda karşınıza büyük bir problem çıkabiliyor. O zaman nasıl bir çözüm yolu var diye araştırırken sevgili StackOverflow’da amcanın biri bu konuda bir soruyu cevaplayarak benimde problemimi çözmüş. Burada paylaşmak istedim. Konu şu : Self-referencing many-to-many relationship code first Entity Framework .

Şimdi önce isterseniz olayı bir anlatayım. Bildiğiniz gibi ağaç yapısı karşımıza hiyerarşik yapılarda çıkmakta. Mesela  kategoriler, organizasyon şemaları gibi. Bu tür yapıları veri tabanında tutarkende, tablolarımızda kendi kendine bağlı yapılar oluşturmak zorunda kalıyoruz. Sql açısından baktığınızda tablonuz içerisine tablonun Primary Key’i ile aynı tipte bir kolon daha yerleştirdiğinizde, ağaç yapısını hazırlamış oluyorsunuz. Ama bu işi Entity Framework ile nasıl modelleyeceğiz. Cevap biraz karmaşık olabilir.

using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;

    /// <summary>
    /// Category Entity
    /// </summary>
    [Table("TCategory", Schema = "Products")]
    [DataContract]
    public class ECategory
    {
        /// <summary>
        /// Gets or sets the category ID.
        /// </summary>
        /// <value>
        /// The category ID.
        /// </value>
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        [Column(Order = 1)]
        [DataMember]
        public virtual int CategoryID { get; set; }

        /// <summary>
        /// Gets or sets the parent ID.
        /// </summary>
        /// <value>
        /// The parent ID.
        /// </value>
        [Column(Order = 2)]
        [DataMember]
        public virtual int? ParentID { get; set; }

        /// <summary>
        /// Gets or sets the name resource ID.
        /// </summary>
        /// <value>
        /// The name resource ID.
        /// </value>
        [Required]
        [Column(Order = 4)]
        [DataMember]
        public virtual string Name { get; set; }

        /// <summary>
        /// Gets or sets the sort order number.
        /// </summary>
        /// <value>
        /// The sort order number.
        /// </value>
        [Required]
        [Column(Order = 5)]
        [DataMember]
        public virtual int SortOrderNumber { get; set; }

        /// <summary>
        /// Gets or sets the timestamp.
        /// </summary>
        /// <value>
        /// The timestamp.
        /// </value>
        [Timestamp]
        [Column(Order = 7)]
        [DataMember]
        public virtual byte[] Timestamp { get; set; }

        /// <summary>
        /// Gets or sets the parent.
        /// </summary>
        /// <value>
        /// The parent.
        /// </value>
        [ForeignKey("ParentID")]
        public virtual ECategory Parent { get; set; }

        /// <summary>
        /// Gets or sets the children.
        /// </summary>
        /// <value>
        /// The children.
        /// </value>
        public virtual ICollection<ECategory> Children { get; set; }

    }

Yapımız böyle. Dikkat ederseniz yapı kendi içinde birbirine bağlanmış durumda. Böylece Ağaç yapısı tesis edilmiş oluyor. Bu yapıyı bu şekilde bırakırsanız o zaman maalesef ki veri girişinde hata ile karşılaşabiliyoruz. Çünkü ParentID’yi null içeremeyecek şekilde ayarlanmamış oluyor. Yani root elementi giremiyorsunuz. root olmayıncada hiç birşey olmuyor tabi. Bu problemi nasıl çözüyoruz. Şimdide buna bakalım. Öncelikle hatırlatmak isterim ki, Attribute’lar ile birçok ince ayarı yapmak mümkün değil bu yüzden bu ayarları yapabilmek için bize override edeceğimiz bir metod sunulmuş. Bu yapıyı kullanabilmek için yazdığımız DataContext sınıfı içerisinde yer alıyor. Şimdi ona bakalım.

using System.Data.Entity;
using System.Linq;

    public class WebContext : DbContext
    {

        /// <summary>
        /// Gets or sets the categories.
        /// </summary>
        /// <value>
        /// The categories.
        /// </value>
        public DbSet<ECategory> Categories { get; set; }

        /// <summary>
        /// This method is called when the model for a derived context has been initialized, but
        /// before the model has been locked down and used to initialize the context.  The default
        /// implementation of this method does nothing, but it can be overridden in a derived class
        /// such that the model can be further configured before it is locked down.
        /// </summary>
        /// <param name="modelBuilder">The builder that defines the model for the context being created.</param>
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            //base.OnModelCreating(modelBuilder);

            modelBuilder.Entity<ECategory>()
                .HasOptional(x => x.Parent)
                .WithMany(x => x.Children)
                .HasForeignKey(x => x.ParentID)
                .WillCascadeOnDelete(false);

            // modelBuilder.Entity<ECategory>()
                // .HasRequired(x => x.Children)
                // .WithMany()
                // .HasForeignKey(x => x.ParentID)
                // .WillCascadeOnDelete(false);

            base.OnModelCreating(modelBuilder);
        }

        #endregion Methods
    }

Dikkat ederseniz override ettiğimiz metod OnModelCreating. Adından da anlaşılıyor zaten :) . Şimdi burada ne oluyor, Sistem attribute’lardan bazı bilgileri alıp toparlıyor ama dediğim gibi bazı ayarlar attribute’lar ile yapılamadığı için biz tam bu noktada bu ayarları yapıyoruz. Mesela

            modelBuilder.Entity<ECategory>()
                .HasOptional(x => x.Parent)
                .WithMany(x => x.Children)
                .HasForeignKey(x => x.ParentID)
                .WillCascadeOnDelete(false);

satırında ECategory entity’sini alıp, bunun içindeki Children property’sini many to many bağlantısı ile konfigüre etmiş oluyoruz. Böylece herşey tam olarak istediğimiz şekilde oluyor.
Yorum satırı şeklindeki kısımda ise önceki ayarlar yer alıyor. Bu aradaki bağlantının one to many şeklinde olması ve cascade işleminin delete için uygulanmaması sağlanmış olmakta.

Entity Framework 4.1 Code First, using Enum Types

When I use a enum type to my Entity Framework 4.1 Code First project, I noticed that the generated database table column (which is my enum type column),  type is nvarchar(max). But I want to that to be tinyint type. So, here is my solution ;

This is the enum type that i use:

    public enum FileTypesEnum : byte
    {
        DataSheet = 1,
        ProductManual = 2,
        Driver = 3,
        Software = 4,
        Image = 5,
        Video = 6
    }

And the property of the poco class :

    [Required]
    [Column("FileType", Order = 2)]
    public FileTypesEnum FileType { get; set; }

but it doesn’t work as i want it to be.
So, i came up with this :

    [Required]    
    [Column("FileTypeValue", Order = 2)]    
    public byte FileTypeValue { get; set; }     
    [NotMapped]    
    public FileTypesEnum FileType     {     
        get { return (FileTypesEnum)FileTypeValue; }        
        set { FileTypeValue = (byte)value; }    
    }

Enjoy!

Sql Server 2008 HierarchyId Tipi

SQL Server 2008 ile beraber hayatımıza giren yeni sql tipi hierarchyid esasında eskiden beri bizim uğraşmamız gereken bir probleme çözüm oluyor. Bildiğiniz gibi hiyerarşik yapıları sql server içinde tutarken nasıl bir yol izleneceği biraz karmaşık bir yol olmuştur. o sebeple bu yeni tip bizim hayatımızı kolaylaştırıyor.

İleriki zamanlarda konu ile ilgili daha geniş bir yazı yazmayı ümit ediyorum, ancak o zamana kadar bilgi alabileceğiniz birkaç adresi sizinle paylaşacağım :

  1. hierarchyid (Transact-SQL) : http://technet.microsoft.com/en-us/library/bb677290.aspx
  2. Using hierarchyid Data Types (Database Engine) : http://technet.microsoft.com/en-us/library/bb677173.aspx
  3. Dmitri Nesteruk tarafından yazılmış güzel bir yazı : http://nesteruk.org/blog/post/Working-with-SQL-Server-hierarchical-data-and-Silverlight.aspx
  4. Working With SQL Server HierarchyId Data Type In .NET Application : http://www.thereforesystems.com/working-with-sql-server-hierarchyid-data-type-in-net-application/
  5. Vasco Oliveira tarafından yazılmış makale : http://blog.vascooliveira.com/sql-server-2008-hierarchyid-data-type-tutorial/
  6. Loading a TreeView using HierarchyID : http://www.codeproject.com/KB/cs/TreeViewFromHierarchyID.aspx
  7. The HierarchyID Datatype in SQL Server 2008 : http://www.sqlservercentral.com/articles/SQL+Server+2008/62204/
  8. SQL Server 2008 – HierarchyID – Part I : http://blogs.msdn.com/b/manisblog/archive/2007/08/17/sql-server-2008-hierarchyid.aspx
  9. SQL Server 2008 – HierarchyID – Part II : http://blogs.msdn.com/b/manisblog/archive/2007/08/28/sql-server-2008-hierarchyid-part-ii.aspx
  10. HierarchyID in Entity Framework not working : http://stackoverflow.com/questions/4316069/hierarchyid-in-entity-framework-not-working

Not: Entity Framework ve Linq To Sql ile kullanmaya çalıştım, ama problemli olduğunu görüp vazgeçtim. tam destek çıkmadan kullanmamanızı öneririm.

SqlException: The parameterized query ## expects the parameter ##, which was not supplied.

Eğer SqlCommand ile çalışırken böyle bir hata ile karşılaşıyorsanız, problem büyük ihtimalle parametrelerin içerdikleri değerlerden kaynaklanıyordur. Böyle bir durumda parametrelerinizin içerdikleri değerleri kontrol edip, eğer null iseler bunları DBNull.Value ile değiştirmeniz probleminizi çözecektir. Bu iş için kısaca şöyle bir kod yazılabilir.

SqlConnection sc = new SqlConnection(“Data Source=…..”);

SqlCommand scom = new SqlCommand(“SELECT ….”, sc);

SqlParameter sp = scom.Parameters.AddWithValue(“@p1”, deger);

if(sp.Value == null) {
    sp.IsNullable=true;
    sp.Value = DBNull.Value;
}
İzmir Yazılım Grubu
Google Groups
Subscribe to İzmir Yazılım Grubu
Email:
Visit this group
Mayıs 2012
Pts Sal Çar Per Cum Cts Paz
« Şub    
 123456
78910111213
14151617181920
21222324252627
28293031  
Yeni Downloadlar
StatPress
Visits today: 95
Sahip oldugum diger adresler :
3dmaxtraining.info
3dmaxtrainings.com
3dmaxtrainings.info
adobelearning.info
adobelearnings.info
adobetrainings.com
adobetrainings.info
autocadbootcamp.info
autocadexams.info
autodesklearning.info
autodesklearnings.com
autodesklearnings.info
ciscotrainings.info
egepro.com
elonunbahcesi.com
elonunbahcesi.info
flashbootcamp.info
flashexams.com
flashexams.info
konuralp.biz
konuralp.org
mayatutorial.info
mayatutorials.info
microsoftexams.info
microsofttrainings.info
proege.com
sharepointlearning.info
sharepointlearnings.com
sharepointlearnings.info
sharepointtutorial.info
silverlightbootcamp.info
silverlightlearning.info
silverlightlearnings.info
silverlighttraining.info
silverlighttrainings.com
silverlighttrainings.info
silverlighttutorial.info
silverlighttutorials.info
sirasende.info
urunbul.info
yagmurca.com
yagmurca.info