Hi, I am Prabhat Sinha. I’m a Senior .NET programmer at Globussoft with 7+ years of experience. I am going to show very simple sample of MLM Tree implementation in ASP.NET with SQL server 2008.
AGENDA: EARNINGS STRUCTURE
When user invites someone to join, the two accounts become linked. Whenever the invited person (L2) makes a purchase, some percentage of their purchase is credited to the account of the user who invited them (L1). (This percentage is usually no more than 3%)
Earnings are counted by the system and displayed on the users’ account information page.
For non-members these earnings are counted on the accounts page, but cannot be cashed out until they pay for a full account.
The earnings system has 4 tiers as seen below. The up-stream payments relationship occurs only between any given user and the L2-L4 users below them. Any further tiers below L4 in their network, ieL5 (friends of L4) are ignored.
So in the pyramid above, assuming no further connections:
•When a L2 makes a purchase, 3% of the purchases are credited to the L1 user
•When a L3 makes a purchase, 3% are credited to the L2 user above them in the pyramid, and 1% is credited to the L1 user
•When a L4 makes a purchase, 3% are credited to the L3 user above them, 1% is credited to the L2 and 0.5% is credited to the L1
Therefore, the earnings system is infinite, but each pyramid within is limited to 4 levels. A given user (User X) will be L2 to another user (User Y), yet when User X invites a new user (User Z), User X remains L2 to User Y, but will become L1 in the new relationship with User Z.
Design for the module:
Solution:
Back end Table Structure:
CREATE TABLE [Bridgin].[MlmUsers]( [Email] [varchar](50) NOT NULL, [Password] [varchar](50) NOT NULL, [Guid] [varchar](100) NULL, [FirstName] [varchar](50) NULL, [LastName] [varchar](50) NULL, [LastLogin] [datetime] NULL, [Mobile] [varchar](50) NULL, [EmailVerified] [bit] NULL, [PhoneVerified] [varchar](50) NULL, [AccountCreated] [datetime] NULL, [JoinUnder] [varchar](100) NULL, [Member] [bit] NULL, [PackageType] [char](1) NULL, [IsActive] [bit] NOT NULL, [RegistrationMethod] [varchar](50) NULL, [Subscribe] [varchar](50) NULL, [City] [nvarchar](50) NULL, [PaymentDate] [datetime] NULL, [PaymentStatus] [bit] NULL, [PayRef] [varchar](50) NULL, [BankHostStatusCode] [varchar](50) NULL, [BankRefNo] [varchar](50) NULL, [AcountHolder] [varchar](50) NULL, CONSTRAINT [PK_MlmUsers_1] PRIMARY KEY CLUSTERED( [Email] ASC ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY]
___________________________________________________________________________________________________
Used Function Structure:
1.
UserDefinedFunction [Bridgin].[funGetT4Tot SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [Bridgin].[funGetT4Tot] ( @T3Emailvarchar(50)) RETURNS Int AS BEGIN DECLARE @TotT3 INT SELECT @TotT3 = COUNT(*) FROM MlmUsers WHERE (JoinUnder = (SELECT Guid FROM MlmUsers WHERE (Email = @T3Email))) RETURN (@TotT3) END GO
2.
UserDefinedFunction [Bridgin].[funGetT3Tot] SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [Bridgin].[funGetT3Tot] ( @T2Email varchar(50) ) RETURNS Int AS BEGIN DECLARE @TotT2 INT SELECT @TotT2 = COUNT(*) FROM MlmUsers WHERE (JoinUnder = (SELECT Guid FROM MlmUsers WHERE (Email = @T2Email))) RETURN (@TotT2) END
3.
UserDefinedFunction [Bridgin].[funGetT3T4] (Main function for call) SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO CREATE FUNCTION [Bridgin].[funGetT3T4] (@T1Emailvarchar(50)) RETURNS @tblGetT3T4 TABLE (Id Int,Emailvarchar(50) , MemberNamevarchar(50), MemberStausvarchar(20), JoiningDatedatetime , networkvarchar(10)) AS BEGIN Declare @T3tot int , @T4tot int,@ID INT Declare @EmailT3 varchar(50), @EmailT4 varchar(50), @MemberNamevarchar(50), @MemberStausvarchar(20), @JoiningDatedatetime , @network varchar(10) SET @T3tot=0 SET @T4tot=0 Declare @MemberTreeT3 CURSOR Declare @MemberTreeT4 CURSOR SET @MemberTreeT3 =CURSOR FOR SELECT MemberTreeDetails.ID, MemberTreeDetails.InvitedEmail, MemberTreeDetails.Name, MemberTreeDetails.Status, MemberTreeDetails.InviteDate FROM [Bridgin].MemberTree INNER JOIN [Bridgin].MemberTreeDetails ON [Bridgin].MemberTree.ID = [Bridgin].MemberTreeDetails.InvitedBy WHERE ([Bridgin].MemberTree.InvitedFrom = @T1Email) AND ([Bridgin].MemberTreeDetails.MemberStatus=1) OPEN @MemberTreeT3 FETCH NEXT FROM @MemberTreeT3 INTO @ID,@EmailT3,@MemberName,@MemberStaus,@JoiningDate WHILE @@FETCH_STATUS = 0 BEGIN SET @T3tot=Bridgin.funGetT3Tot(@EmailT3) SET @MemberTreeT4 =CURSOR FOR Select Email FROM [Bridgin].MLMUsers WHERE (JoinUnder = (SELECT GuidFROM [Bridgin].MlmUsers WHERE (Email = @EmailT3))) OPEN @MemberTreeT4 FETCH NEXT FROM @MemberTreeT4 INTO @EmailT4 WHILE @@FETCH_STATUS = 0 BEGIN SET @T4tot=Bridgin.funGetT4Tot(@EmailT4) FETCH NEXT FROM @MemberTreeT4 INTO @EmailT4 End INSERT INTO @tblGetT3T4 (Id,Email, MemberName, MemberStaus,JoiningDate, network ) VALUES (@ID, @EmailT3,@MemberName,@MemberStaus,@JoiningDate,CAST(@T3tot AS VARCHAR(5))+ '(' + CAST(@T4tot AS VARCHAR(5)) + ')') SET @T3tot=0 SET @T4tot=0 FETCH NEXT FROM @MemberTreeT3 INTO @ID,@EmailT3,@MemberName,@MemberStaus,@JoiningDate END RETURN END
___________________________________________________________________________________________________
About Function in SQL:
In SQL databases, a user-defined function provides a mechanism for extending the functionality of the Database Server by adding a function that can be evaluated in SQL statements. The SQL standard distinguishes between Scalar and table functions. A scalar function returns only a single value (or NULL), whereas a table function returns a (relational) table comprising zero or more rows, each row with one or more columns.
http://www.dotnet-tricks.com/Tutorial/sqlserver/KY3T010412-Different-Types-of-SQL-Server-Functions.html
http://technet.microsoft.com/en-us/library/ms191320.aspx
About Cursor in Sql:
A cursor is a set of rows together with a pointer that identifies a current row.
In other words, cursor is a database object used by applications to manipulate data in a set on a row-by-row basis, it’s like record set in ASP and Visual Basic.
http://technet.microsoft.com/en-us/library/ms180169.aspx/
http://www.dotnet-tricks.com/Tutorial/sqlserver/4L7I050512-SQL-Server-Basics-of-Cursors.html
Procedure for Front End:
Added function on dbml file in asp.net:
Code on page:
To call MLM Tree function:
privatevoidGridBind() { Member = User.Identity.Name; try{ GVNetworkMemberStatus.DataSource = DbContext.funGetT3T4(Member); GVNetworkMemberStatus.DataBind(); } catch (Exception) { throw; } }
Finally,the screen form will look like:
Conclusion: In UDF:
Advantages:
• They allow modular programming.
• They allow faster execution.
• They can reduce network traffic.
Disadvantages:
The main “disadvantage” of user-defined functions is that they are called for each row. So, if you have such a function in the SELECT list and you’re operating on larger sets, there are good chances that your performance will suffer.