none
Inheritance in Linq to SQL RRS feed

  • Question

  • Hi i want to create a base class to inherite from my all classes in linq. this class will include ObjectId (Primary key) and some other properties.  This class will include common properties but these properties are special to codding standarts like ObjectId, CreationDate !! NOT LIKE PERSON -> EMPLOYEEE etc relation

    For Example

     

    public class Base
    
    {
    
    [Column]
    
    prop ObjectId
    
    }
    
    [Table]
    
    public class Customer: Base
    
    {
    
    [Column]
    
    prop name;
    
    [Column]
    
    prop surname;
    
    .
    
    .
    
    }
    
    [Table]
    
    public class Product:Base
    
    {
    
    prop ProductId;
    
    prop ProductName;
    
    }
    

    !!IMPORTANT!!  I will inherite the base class from all my classes in my project


    i can write this code and debug there is no compilation error bur when i create the context and try to create database with the ctx.CreateDatabase();  function it is not possible.

    Is there any mistake in my structure . Doesnt LINQ support this

    • Moved by Martin_Xie Monday, September 12, 2011 4:14 AM Move it to LINQ Forum for better support. (From:Visual C# Language)
    Sunday, September 11, 2011 3:15 PM

Answers

  • Hi Okan,

     

    Have you looked at this link - http://blogs.msdn.com/b/dinesh.kulkarni/archive/2007/11/09/linq-to-sql-how-to-2-base-class-for-all-entities.aspx ?

     

    In summary you can create your base class and have the generated classes inherit from that. You then need to extend the generated classes in an new file (they are partial) and hand-craft the overrides of the common properties. The blog gives a similar example to yours but  implementing "ID" instead of "ObjectId". Note that all mapping to the database is done in the classes not the base.

     

    Your dbml file needs to contain the name of the base class in it's header.

    If you are using the Designer Surface then you need to manually change the header to include something like the following.

    <Database Name="Northwind" EntityNamespace="Blah" ContextNamespace="Blah" Class="DataClassesDataContext" EntityBase="Base" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">

    If you are using SqlMetal, then use "/entitybase:base".

    In both cases when you generate your DataClasses.designer.cs, the classes will now inherit from Base.

     

    Generated Code (e.g. DataClasses.designer.cs)

     

    	// Don't change any of this manually
    
    	// Note that this inherits from base now
    	public partial class Customer : Base, INotifyPropertyChanging, INotifyPropertyChanged
    	{
    		[Column(Storage="_clientName", DbType="NVarChar(40)")]
    		public string clientName
    		{
    			get
    			{
    				return this._clientName;
    			}
    			set
    			{
    				if ((this._clientName != value))
    				{
    					this.OnclientNameChanging(value);
    					this.SendPropertyChanging();
    					this._clientName = value;
    					this.SendPropertyChanged("clientName");
    					this.OnclientNameChanged();
    				}
    			}
    		}		
    	}
    


     

    YourExtensions.cs

     

    	public abstract class Base
    	{
    		public virtual string Name { get; set; }
    	}
    
    	// Extend the partial class by adding a Name override
    	public partial class Customer : Base
    	{
    		// I'm not sure if the ColumnAttribute is required because this property is just masking this.ClientName which already has the mapping
    		[Column(Storage="_clientName", DbType="NVarChar(40)")]
    		public override string Name
    		{
    			get { return this.clientName; }
    			set { this.clientName; = value; }
    		}
    	}
    


    Cheers,

    John.

     

    Tuesday, September 20, 2011 8:20 AM

All replies

  • Hi Okan,

    The DataContext.CreateDatabase method creates a replica of the database only to the extent of the information encoded in the object model. Mapping files and attributes from your object model might not encode everything about the structure of an existing database. Mapping information does not represent the contents of user-defined functions, stored procedures, triggers, or check constraints. This behavior is sufficient for a variety of databases.(http://msdn.microsoft.com/en-us/library/bb399420.aspx). LINQ to SQL couldn't find the properties from the children type.

    I think you can try EF code First mapping inheritance. There are 3 inheritances in EF: TPC, TPT, TPH.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, September 12, 2011 9:40 AM
    Moderator
  • Hi,

    I am writing to check the status of the issue on your side. Would you mind letting us know the result of the suggestions?

    If you need further assistance, please feel free to let me know. I will be more than happy to be of assistance.

    Have a nice day.


    Alan Chen[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, September 19, 2011 7:41 AM
    Moderator
  • i am searching for more information about this subject. I understood that my code is not possible at this time but i think there are different soluitons about this subject
    Okan SARICA
    Tuesday, September 20, 2011 6:45 AM
  • Hi Okan,

     

    Have you looked at this link - http://blogs.msdn.com/b/dinesh.kulkarni/archive/2007/11/09/linq-to-sql-how-to-2-base-class-for-all-entities.aspx ?

     

    In summary you can create your base class and have the generated classes inherit from that. You then need to extend the generated classes in an new file (they are partial) and hand-craft the overrides of the common properties. The blog gives a similar example to yours but  implementing "ID" instead of "ObjectId". Note that all mapping to the database is done in the classes not the base.

     

    Your dbml file needs to contain the name of the base class in it's header.

    If you are using the Designer Surface then you need to manually change the header to include something like the following.

    <Database Name="Northwind" EntityNamespace="Blah" ContextNamespace="Blah" Class="DataClassesDataContext" EntityBase="Base" xmlns="http://schemas.microsoft.com/linqtosql/dbml/2007">

    If you are using SqlMetal, then use "/entitybase:base".

    In both cases when you generate your DataClasses.designer.cs, the classes will now inherit from Base.

     

    Generated Code (e.g. DataClasses.designer.cs)

     

    	// Don't change any of this manually
    
    	// Note that this inherits from base now
    	public partial class Customer : Base, INotifyPropertyChanging, INotifyPropertyChanged
    	{
    		[Column(Storage="_clientName", DbType="NVarChar(40)")]
    		public string clientName
    		{
    			get
    			{
    				return this._clientName;
    			}
    			set
    			{
    				if ((this._clientName != value))
    				{
    					this.OnclientNameChanging(value);
    					this.SendPropertyChanging();
    					this._clientName = value;
    					this.SendPropertyChanged("clientName");
    					this.OnclientNameChanged();
    				}
    			}
    		}		
    	}
    


     

    YourExtensions.cs

     

    	public abstract class Base
    	{
    		public virtual string Name { get; set; }
    	}
    
    	// Extend the partial class by adding a Name override
    	public partial class Customer : Base
    	{
    		// I'm not sure if the ColumnAttribute is required because this property is just masking this.ClientName which already has the mapping
    		[Column(Storage="_clientName", DbType="NVarChar(40)")]
    		public override string Name
    		{
    			get { return this.clientName; }
    			set { this.clientName; = value; }
    		}
    	}
    


    Cheers,

    John.

     

    Tuesday, September 20, 2011 8:20 AM