All Projects → maliming → Abp.generaltree

maliming / Abp.generaltree

Licence: mit
For Abp vNext

Projects that are alternatives of or similar to Abp.generaltree

react-tree
Hierarchical tree component for React in Typescript
Stars: ✭ 174 (+64.15%)
Mutual labels:  tree, tree-structure
prune
A tree library for Java 8 with functional sensibilities.
Stars: ✭ 22 (-79.25%)
Mutual labels:  tree, tree-structure
TreeRep
Learning Tree structures and Tree metrics
Stars: ✭ 18 (-83.02%)
Mutual labels:  tree, tree-structure
mongodb-tree-structure
Implementing Tree Structure in MongoDB
Stars: ✭ 14 (-86.79%)
Mutual labels:  tree, tree-structure
Bosket
Collection of tree view components for front-end frameworks. 🌳
Stars: ✭ 457 (+331.13%)
Mutual labels:  tree, tree-structure
vue-virtualised
Blazing fast scrolling and updating for any amount of list and hierarchical data.
Stars: ✭ 18 (-83.02%)
Mutual labels:  tree, tree-structure
stefano-tree
Framework agnostic Nested Set (MPTT) implementation for PHP
Stars: ✭ 24 (-77.36%)
Mutual labels:  tree, tree-structure
Array To Tree
Convert a plain array of nodes (with pointers to parent nodes) to a nested data structure
Stars: ✭ 141 (+33.02%)
Mutual labels:  tree, tree-structure
Wmderland
🌳 X11 tiling window manager using space partitioning trees
Stars: ✭ 341 (+221.7%)
Mutual labels:  tree, tree-structure
tree-json-generator
Simple JavaScript Tree Generator library
Stars: ✭ 13 (-87.74%)
Mutual labels:  tree, tree-structure
ng-treetable
A treetable module for angular 5
Stars: ✭ 32 (-69.81%)
Mutual labels:  tree, tree-structure
Ki
Go language (golang) full strength tree structures (ki in Japanese)
Stars: ✭ 61 (-42.45%)
Mutual labels:  tree, tree-structure
Relation Classification Using Bidirectional Lstm Tree
TensorFlow Implementation of the paper "End-to-End Relation Extraction using LSTMs on Sequences and Tree Structures" and "Classifying Relations via Long Short Term Memory Networks along Shortest Dependency Paths" for classifying relations
Stars: ✭ 167 (+57.55%)
Mutual labels:  tree, tree-structure
performant-array-to-tree
Converts an array of items with ids and parent ids to a nested tree in a performant O(n) way. Runs in browsers and Node.js.
Stars: ✭ 193 (+82.08%)
Mutual labels:  tree, tree-structure
Graphview
Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful for Family Tree, Hierarchy View.
Stars: ✭ 152 (+43.4%)
Mutual labels:  tree, tree-structure
treetime
TreeTime is a data organisation, management and analysis tool. A tree is a hierarchical structure that arranges information in units and sub-units. TreeTime uses linked trees (one data item can be part of different distinct trees) to store and organise any general purpose data.
Stars: ✭ 26 (-75.47%)
Mutual labels:  tree, tree-structure
Bplustree
A minimal but extreme fast B+ tree indexing structure demo for billions of key-value storage
Stars: ✭ 1,598 (+1407.55%)
Mutual labels:  tree, tree-structure
Containers
This library provides various containers. Each container has utility functions to manipulate the data it holds. This is an abstraction as to not have to manually manage and reallocate memory.
Stars: ✭ 125 (+17.92%)
Mutual labels:  tree, tree-structure
react-treefold
A renderless tree component for your hierarchical React views
Stars: ✭ 37 (-65.09%)
Mutual labels:  tree, tree-structure
Angular2 Tree Diagram
Angular Hierarchical UI module
Stars: ✭ 50 (-52.83%)
Mutual labels:  tree, tree-structure

Abp GeneralTree

NuGet

GeneralTree中文文档

  • Based on Abp module system, perfect integration Abp framework.
  • Support for custom primary key (value type, reference type).
  • Automating the assignment of Code,Level,FullName extends other attributes of the entity.
  • Efficient management of entities based on Code, Level features.
  • Suitable for managing a variety of tree structure entities, such as: region, organization, category, industry and other entities with parent-child Entity.

Installation

Install-Package Abp.GeneralTree
dotnet add package Abp.GeneralTree

First you need to add the dependency to your module:

[DependsOn(typeof(GeneralTreeModule))]
public class YourProjectModule : AbpModule
{
    //...
}

GeneralTree provides a generic IGeneralTree interface, which inherits this interface, passing in generic parameter entities and primary keys (primary keys can be value types and reference types)

Value type

public interface IGeneralTree<TTree, TPrimaryKey> : IEntity<TPrimaryKey>
    where TPrimaryKey : struct
{
      string Name { get; set; }

      string FullName { get; set; }

      string Code { get; set; }

      int Level { get; set; }

      TTree Parent { get; set; }

      TPrimaryKey? ParentId { get; set; }

      ICollection<TTree> Children { get; set; }
}

Reference type

public interface IGeneralTreeWithReferenceType<TTree, TPrimaryKey> : IEntity<TPrimaryKey>
    where TPrimaryKey : class
{
      string Name { get; set; }

      string FullName { get; set; }

      string Code { get; set; }

      int Level { get; set; }

      TTree Parent { get; set; }

      TPrimaryKey ParentId { get; set; }

      ICollection<TTree> Children { get; set; }
}

Take the Region entity as an example:

public class Region : Entity<long>, IGeneralTree<Region, long>
{
      public virtual string Name { get; set; }

      public virtual string FullName { get; set; }

      public virtual string Code { get; set; }

      public virtual int Level { get; set; }

      public virtual Region Parent { get; set; }

      public virtual long? ParentId { get; set; }

      public virtual ICollection<Region> Children { get; set; }
}

Entities implement properties under generic interfaces, and GeneralTree automatically maintains these properties (FullName, Code, Level, ParentId...)

To create, update, move, delete, etc., use IGeneralTreeManager<TTree, TPrimaryKey>, and the generic parameters of the interface are the same as above.

Use

We first initialize some regional information.

var beijing = new Region
{
      Name = "beijing"
};
await _generalRegionTreeManager.CreateAsync(beijing);

At this time, the entity information of beijing is as follows:

Id Name FullName Code Level ParentId
1 beijing beijing 00001 1 NULL

GeneralTree automatically maintains the modified properties. It provides the basis for efficient management later.

Add some areas again.

var beijing = new Region
{
      Name = "beijing"
};
await _generalRegionTreeManager.CreateAsync(beijing);
await CurrentUnitOfWork.SaveChangesAsync();

var dongcheng = new Region
{
      Name = "dongcheng",
      ParentId = beijing.Id
};

var xicheng = new Region
{
      Name = "xicheng",
      ParentId = beijing.Id
};
await _generalRegionTreeManager.CreateAsync(dongcheng);
await _generalRegionTreeManager.CreateAsync(xicheng);

var hebei = new Region
{
      Name = "hebei"
};
await _generalRegionTreeManager.CreateAsync(hebei);
await CurrentUnitOfWork.SaveChangesAsync();

var shijianzhuang = new Region
{
      Name = "shijianzhuang",
      ParentId = hebei.Id
};
await _generalRegionTreeManager.CreateAsync(shijianzhuang);
await CurrentUnitOfWork.SaveChangesAsync();

var changanqu = new Region
{
      Name = "changanqu",
      ParentId = shijianzhuang.Id
};
var qiaoxiqu = new Region
{
      Name = "qiaoxiqu",
      ParentId = shijianzhuang.Id
};
await _generalRegionTreeManager.CreateAsync(changanqu);
await _generalRegionTreeManager.CreateAsync(qiaoxiqu);

The results are as follows:

Id Name FullName Code Level ParentId
1 beijing beijing 00001 1 NULL
2 dongcheng beijing-dongcheng 00001.00001 2 1
3 xicheng beijing-xicheng 00001.00002 2 1
4 hebei hebei 00002 1 NULL
5 shijianzhuang hebei-shijianzhuang 00002.00001 2 4
6 changanqu hebei-shijianzhuang-changanqu 00002.00001.00001 3 5
7 qiaoxiqu hebei-shijianzhuang-qiaoxiqu 00002.00001.00002 3 5

The above operation has a batch method BulkCreateAsync

var beijing = new Region
{
      Name = "beijing",
      Children = new List<Region>
      {
            new Region
            {
                  Name = "dongcheng"
            },
            new Region
            {
                  Name = "dongcheng"
            }
      }
};
await _generalRegionTreeManager.BulkCreateAsync(beijing);
await CurrentUnitOfWork.SaveChangesAsync();

var hebei = new Region
{
      Name = "hebei",
      Children = new List<Region>
      {
            new Region
            {
                  Name = "shijiazhuang",
                  Children = new List<Region>
                  {
                        new Region
                        {
                              Name = "changanqu"
                        },
                        new Region
                        {
                              Name = "qiaodongqu"
                        }
                  }
            }
      }
};
await _generalRegionTreeManager.BulkCreateAsync(hebei);
await CurrentUnitOfWork.SaveChangesAsync();

Some operations of the tree entity

// Query all areas below Beijing does not include Beijing)
var beijing = await _regionRepository.FirstOrDefaultAsync(x => x.Name == "beijing");
var beijingChildren = _regionRepository.GetAll().Where(x => x.Id != beijing.Id && x.Code.StartsWith(beijing.Code));

// Query the area below Beijing (all districts)
var beijing = await _regionRepository.FirstOrDefaultAsync(x => x.Name == "beijing");
var beijingChildren = _regionRepository.GetAll().Where(x => x.Level == beijing.Level - 1 && x.Code.StartsWith(beijing.Code));

// Query Changan and all the parent above
var changanqu = await _regionRepository.FirstOrDefaultAsync(x => x.Name == "changanqu");
var parents = await _regionRepository.GetAllListAsync(x => changanqu.Code.StartsWith(x.Code));

// Query Changan top parent.
var changanqu = await _regionRepository.FirstOrDefaultAsync(x => x.Name == "changanqu");
var hebei =  await _regionRepository.FirstOrDefaultAsync(x => x.Level == 1 && changanqu.Code.Contains(x.Code));

Other

public interface IGeneralTreeManager<TTree, TPrimaryKey>
      where TPrimaryKey : struct
      where TTree : class, IGeneralTree<TTree, TPrimaryKey>
{
      Task CreateAsync(TTree tree);

      Task BulkCreateAsync(TTree tree, Action<TTree> childrenAction = null);

      Task CreateChildrenAsync(TTree parent, ICollection<TTree> children, Action<TTree> childrenAction = null);

      Task FillUpAsync(TTree tree, Action<TTree> childrenAction = null);

      Task UpdateAsync(TTree tree, Action<TTree> childrenAction = null);

      Task MoveAsync(TPrimaryKey id, TPrimaryKey? parentId, Action<TTree> childrenAction = null);

      Task DeleteAsync(TPrimaryKey id);
}

Custom

public override void PreInitialize()
{
      // Custom error message
      Configuration.Modules.GeneralTree<Region, long>().ExceptionMessageFactory = tree => $"{tree.Name} already exists!.";

      // Custom node with the same name additional judgment logic
      Configuration.Modules.GeneralTree<Region, long>().CheckSameNameExpression = (regionThis, regionCheck) => regionThis.SomeForeignKey == regionCheck.SomeForeignKey

      // Custom FullName separator
      Configuration.Modules.GeneralTree<Region, long>().Hyphen = "=>";

}

The above code is for the entity's primary key as the value type. If it is a reference type, please use IGeneralTreeWithReferenceType and IGeneralTreeManagerWithReferenceType

Configure GeneralTreeCodeGenerateCode length (default is 5 digits)

[Fact]
public void Test_CreateCode_With_Length()
{
      var generate = new GeneralTreeCodeGenerate(new GeneralTreeCodeGenerateConfiguration()
      {
            CodeLength = 3
      });

      generate.CreateCode().ShouldBe(null);
      generate.CreateCode(42).ShouldBe("042");
      generate.CreateCode(1, 2).ShouldBe("001.002");
      generate.CreateCode(1, 2, 3).ShouldBe("001.002.003");
}

GeneralTreeExtensions ToTree converts the Tree collection to TreeDto (has a hierarchical relationship, sortable)

[Fact]
public void ToTreeOrderBy_Test()
{
      var regions = new List<Regin>
      {
            new Regin
            {
                  Id = 1,
                  Name = "beijing"
            },
            new Regin
            {
                  Id = 2,
                  Name = "bdongcheng",
                  ParentId = 1
            },
            new Regin
            {
                  Id = 3,
                  Name = "axicheng",
                  ParentId = 1
            },
            new Regin
            {
                  Id = 4,
                  Name = "aHebei"
            },
            new Regin
            {
                  Id = 5,
                  Name = "bShijianzhuang",
                  ParentId = 4
            },
            new Regin
            {
                  Id = 6,
                  Name = "aChengde",
                  ParentId = 4
            },
            new Regin
            {
                  Id = 7,
                  Name = "bShuangqiao",
                  ParentId = 6
            },
            new Regin
            {
                  Id = 8,
                  Name = "aShuangluan",
                  ParentId = 6
            }
      };

      var tree = regions.ToTreeOrderBy<Regin, long, string>(x => x.Name).ToList();

      tree.First().Name.ShouldBe("aHebei");
      tree.First().Children.First().Name.ShouldBe("aChengde");
      tree.First().Children.First().Children.First().Name.ShouldBe("aShuangluan");
}
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].