I cannot make association in my database (Fluent)

2 posts, 0 answers
  1. Marko Gluhak
    Marko Gluhak avatar
    68 posts
    Member since:
    Apr 2006

    Posted 29 Oct 2015 Link to this post

    Hi,

     

    I'm starting to use Fluent Mapping and I have stuck on creating association. I have self referenced class. Fields are: private int _idCategory;

    private int _idCategory;
    public int IdCategory
    {
        get { return _idCategory; }
        set { _idCategory = value; }
    }
     
    private int _idCategoryParent;
    public int IdCategoryParent
    {
        get { return _idCategoryParent; }
        set { _idCategoryParent = value; }
    }
     
    private bool _isLeaf;
    public bool IsLeaf
    {
        get { return _isLeaf; }
        set { _isLeaf = value; }
    }
     
    private string _categoryName;
    public string CategoryName
    {
        get { return _categoryName; }
        set { _categoryName = value; }
    }
     
    private string _categoryDescription;
    public string CategoryDescription
    {
        get { return _categoryDescription; }
        set { _categoryDescription = value; }
    }
     
    public cCategory()
    {
        CategoryName = "SomeValue";
        CategoryDescription = "SomeValue";
        IsLeaf = false;
    }
     
     
    /* ASSOCIATIONS */
    private IList<cCategory> _childCategories = new List<cCategory>();
    public virtual IList<cCategory> ChildCategories
    {
        get
        {
            return this._childCategories;
        }
    }
     
    private cCategory _parentCategory;
    public virtual cCategory ParentCategory
    {
        get
        {
            return this._parentCategory;
        }
        set
        {
            this._parentCategory = value;
        }
    }

    I have metadatasource:
    protected override IList<MappingConfiguration> PrepareMapping()
    {
        var mappingConfigurations = new List<MappingConfiguration>();
     
        MappingConfiguration<cCategory> categoryConfiguration = this.Get_Category_Configuration();
        mappingConfigurations.Add(categoryConfiguration);
     
        return mappingConfigurations;
    }
     
    protected override MetadataContainer CreateModel()
    {
        Telerik.OpenAccess.Metadata.MetadataContainer model = base.CreateModel();
        model.DefaultMapping.NullForeignKey = true;
        return model;
    }
     
     
    #region Category table
    /********************************************************************************                                            CATEGORY
    ********************************************************************************/
    public MappingConfiguration<cCategory> Get_Category_Configuration()
    {
        MappingConfiguration<cCategory> configuration = this.Get_Category_ClassConfiguration();
        this.Prepare_Category_PropertyConfigurations(configuration);
        this.Prepare_Category_AssociationConfigurations(configuration);
        return configuration;
    }
     
    public MappingConfiguration<cCategory> Get_Category_ClassConfiguration()
    {
        var configuration = new MappingConfiguration<cCategory>();
     
        var namingRules = new Telerik.OpenAccess.Metadata.NamingRules();
        namingRules.CaseMode = Telerik.OpenAccess.Metadata.CaseChangeModes.CamelCase;
        namingRules.AddPrefix = "_";
        configuration.FieldNamingRules = namingRules;
     
        configuration.MapType(x => new { }).WithDataAccessKind(DataAccessKind.ReadOnly).WithConcurencyControl(OptimisticConcurrencyControlStrategy.Changed).ToTable(tableName: "Category");
     
        return configuration;
    }
     
     
    public void Prepare_Category_PropertyConfigurations(MappingConfiguration<cCategory> configuration)
    {
        configuration.HasProperty(x => x.IdCategory).IsIdentity(KeyGenerator.Autoinc).WithDataAccessKind(DataAccessKind.ReadWrite).ToColumn(columnName: "IdCategory").IsNullable().HasColumnType(typeName: "int").HasPrecision(precision: 0).HasScale(scale: 0);
        configuration.HasProperty(x => x.IdCategoryParent).WithDataAccessKind(DataAccessKind.ReadWrite).ToColumn(columnName: "IdCategoryParent").IsNullable().HasColumnType(typeName: "int").HasPrecision(precision: 0).HasScale(scale: 0);
        configuration.HasProperty(x => x.IsLeaf).WithDataAccessKind(DataAccessKind.ReadWrite).ToColumn(columnName: "IsLeaf").IsNotNullable().HasColumnType(typeName: "bit").HasPrecision(precision: 0).HasScale(scale: 0);
        configuration.HasProperty(x => x.CategoryName).WithDataAccessKind(DataAccessKind.ReadWrite).ToColumn(columnName: "CategoryName").IsNotNullable().HasColumnType(typeName: "nvarchar").HasLength(length: 50);
        configuration.HasProperty(x => x.CategoryDescription).WithDataAccessKind(DataAccessKind.ReadWrite).ToColumn(columnName: "CategoryDescription").IsNotNullable().HasColumnType(typeName: "nvarchar").HasLength(length: 255);
     
    }
     
    public void Prepare_Category_AssociationConfigurations(MappingConfiguration<cCategory> configuration)
    {
        configuration.HasAssociation(x => x.ChildCategories).WithOpposite(x => x.ParentCategory).HasConstraint((x, y) => x.IdCategoryParent == y.IdCategory).IsManaged().WithDataAccessKind(DataAccessKind.ReadWrite);
    }
     
     
    #endregion

    Table is created but no association and foreign key is created in DB.

    With regards,
    Marko

  2. Pavel Uzunov
    Admin
    Pavel Uzunov avatar
    14 posts

    Posted 03 Nov 2015 Link to this post

    Hi Marko Gluhak,

    Your code is absolutely fine and it works correctly, but Telerik Data Access does not support constraints on self-referencing associations because they need special handling of the insert and delete order. For normal one-to-many associations Data Access calculated this order based on the table definitions and first inserts the record holding the primary key. But for self-references, the table is only one and this mechanism does not work, also there could be cyclic references that could cause problems.
    I am afraid that you will not be able to create those constraints automatically and the only option at the moment is to do that manually in the database.

    I hope the provided information is helpful.

    Regards,
    Pavel Uzunov
    Telerik
     
    Check out the latest announcement about Telerik Data Access vNext as a powerful framework able to solve core development problems.
  3. DevCraft banner
Back to Top