update index after a delete operation - c#

I have a Customer Table that has a CustIndex column. From the UI a User can delete a customer that was for example at Index 3. What I need to do then determine if there was a Customer with an Index at 4 and renumber it to be 3, (so basically keep the sequence).
At the minute I just have some code like below:
private void UpdateCustomerIndexes(IList<CustomerDTO> customers)
{
var customerIndexes = customers.Select(c => new { c.customerId, c.customerIndex });
//unitIndexes.Select(u => u.)
}
I am keeping wanting to keep the CustomerId so if I need to update the DB I can say update customer set index = 3 where customerid = 4 for example.
So if I had 5 customer on the UI and I delete Customer at Index 5
If I set a breakpoint on customerIndexes, the data is:
{ CustomerId = 33, CustomerIndex = 1 },
{ CustomerId = 34, CustomerIndex = 2 },
{ CustomerId = 35, CustomerIndex = 3 },
{ CustomerId = 36, CustomerIndex = 4 }
So, in this case, the CustomerIndex is in sequence so there is nothing to do. However, lets say now I deleted CustomerIndex 2 on the UI. The data would now look like:
{ CustomerId = 33, CustomerIndex = 1 },
{ CustomerId = 35, CustomerIndex = 3 },
{ CustomerId = 36, CustomerIndex = 4 }
Now the Customer Index is out of sequence and I need to renumber CustomerIndex 3 to 2 and CustomerIndex 4 to 3 and then save this to the DB so I can say make the update statements setting the Index to the new value for that CustomerId.
I know my CustomerIndex will never go above 50 so would it be an idea to use something like:
var list = new List<int>(new[] { customerIndexes.Select(c => c.customerIndex) });
var result = Enumerable.Range(0, 50).Except(list);
However, I think this will only tell me if a number in sequence is missing - I am missing how to save which index needs to be updated for which customerid or do nothing in the case when they are in sequence

After you delete the record with CustomerIndex of 2, run the following SQL:
UPDATE TableName SET CustomerIndex = CustomerIndex - 1 WHERE CustomerIndex > 2
This will ensure the CustomerIndex of all 'greater' records are reduced by 1 to compensate.
Similarly, if a customer deletes CustomerIndex of 5, change both references to 2 above to 5.

Related

Select if condition matches with only one specific value

I have a linq query where I am trying to select the name of the user if (s)he has a spesific role. But I want it to be selected, if and only if (s)he has only the targeted spesific role, not with the other spesified roles(such as General Manager and Purchase Manager).
DepartmentManagerName = (from r in efDB.TBL_TABNET_REL_USER_ROLE
where (h.Confirm_By == r.TBL_USER.ID) && r.TBL_TABNET_DEF_ROLE.ID == (int)Enums.UserRank.Manager
select r.TBL_USER.Name + " " + r.TBL_USER.Surname).FirstOrDefault(),
One user can have multiple roles in the table, such as being "Department Manager" and "General Manager" together. Here is the example from the table TBL_TABNET_DEF_ROLE;
ID UserID RoleID
123 40 2
126 40 5
127 36 2
128 42 2
129 49 2
130 55 2
131 59 2
132 61 2
133 76 2
134 77 2
But when I am assigning to the DepartmentManagerName variable, I don't want it to be assigned if the user has also the "General Manager" role. Because of the reason "Department Manager" role comes earlier than "General Manager" role in the database table, the where condition is being true and the user name is assigned to DepartmentManagerName variable even in next iterations it will be identified that user also has the role of "General Manager". But I want to achieve that there will be no assignment if any other role matched other than "Department Manager". How could I achieve that?
I think of something like this to solve your problem, it will get the UserId of the first user that have only one role and the RoleId == 2 (in my example).
public static void Main()
{
var table = new List<TBL_USER>
{
new TBL_USER(1, 1, 1),
new TBL_USER(2, 1, 2),
new TBL_USER(3, 2, 1),
new TBL_USER(5, 4, 1),
new TBL_USER(6, 4, 2),
new TBL_USER(7, 5, 1),
new TBL_USER(8, 5, 2),
new TBL_USER(9, 5, 3)
};
var user = table
.GroupBy(tbl => tbl.UserId) // Group the lines with the same UserId
.Where(grp => grp.Any(u => u.RoleId == 1) && grp.All(u => u.RoleId != 2)) // Get the groups that have a RoleId as 1 and not RoleId as 2
.FirstOrDefault().Key; // Get the first group and get the Key (UserId)
}
public class TBL_USER
{
public int Id { get; set; }
public int UserId { get; set; }
public int RoleId { get; set; }
public TBL_USER(int id, int user, int role)
{
Id = id;
UserId = user;
RoleId = role;
}
}

Mapping values in dropdown

Table 1:
ID
1
2
3
4
5
6
7
8
9
0
I have to create dropdowns called MasterID & ChildID out of this ID column. MasterID & ChildID will have ID column values based on mapping. Mapping process will be like any values from the ID column can be MasterID or ChildID. But MasterID will have unique ChildID.
Note: While binding MasterID and ChildID dropdowns it will have ID values on pageload. Once mapping starts then the values should come accordingly. Also I have a Add button in my page and once I select values in two dropdowns and add then they will get saved in the DB.
For ex: If I select the ID value 1 in MasterID and 5 in ChildID and add them to DB, then the next time the value 1 from ID column can come in MasterID dropdown but not in ChildID. Also the value 5 from ID column is mapped to ChildID and saved, where this value should not appear in MasterID and ChildID dropdowns. Once any value is selected as the ChildID and saved, then it shouldn't get displayed inMasterIDor inChildID` dropdowns.
Final Output should be like this.
Table 2:
MasterID ChildID
1 5
2 3
2 6
4 7
4 8
9 0
Can anyone help me or suggest how I can achieve this for asp.net web application.
You can use LINQ to filter the values that you need to display in both the dropdowns.
Something like following.
int[] table1 = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
int[] tableMaster = new int[] { 1, 2, 2, 4, 4, 9 };
int[] tableChild = (from t in table1
where !tableMaster.Contains(t)
select t).ToArray();
Note: This is just an example so that you get an idea.

Using Linq to get the last N number of rows that have duplicated values in a field

Given a database table, a column name C, and a number N larger than 1, how can I get a group of rows with equal values of column C which has at least N rows? If there exists more than one such group, I need to get the group which contains the newest entry (the one with the largest Id).
Is it possible to do this using LINQ to Entities?
Example:
> Id | Mycolumn
> - - - - - - -
> 1 | name55555
> 2 | name22
> 3 | name22
> 4 | name22
> 5 | name55555
> 6 | name55555
> 7 | name1
Primary Key: ID
OrderBy: ID
Repeated column: Mycolumn
If N = 3 and C = Mycolumn, then we need to get rows which have the column MyColumn duplicated at least 3 times.
For the example above, it should return rows 1, 5 and 6, because last index of name55555 is 6, and last index of name22 (which is also repeated 3 times) is 4.
data.Mytable
.OrderByDescending(m => m.Id)
.GroupBy(m => m.Mycolumn)
.FirstOrDefault(group => group.Count() >= N)
.Take(N)
.Select(m => m.Id)
If the rows are identical (all columns) then frankly there's no point fetching more than one of each - they will be indistinguishable; I don't know about LINQ, but you can do something like:
select id, name /* more cols */, count(1) from #foo
group by id, name /* more cols */ having count(1) > 1
You can probably do that in link using GroupBy etc. If they aren't entirely identical (for example, the IDENTITY is different, but the other columns are the same), it gets more difficult, and certainly there is no easy LINQ syntax for it; at the TSQL level, though:
select id, name /* more cols */
from (
select id, name /* more cols */,
ROW_NUMBER() over (partition by name /* more cols */ order by id) as [_row]
from #foo) x where x._row > 1
I have scratched this together in Linqpad, which should give you the wanted results:
int Border = 3;
var table = new List<table>
{
new table {Id = 1, Value = "Name1"},
new table {Id = 2, Value = "Name2"},
new table {Id = 3, Value = "Name5"},
new table {Id = 4, Value = "Name5"},
new table {Id = 5, Value = "Name2"},
new table {Id = 6, Value = "Name5"},
new table {Id = 7, Value = "Name5"},
};
var results = from p in table
group p.Id by p.Value into g
where g.Count() > Border
select new {rows = g.ToList()};
//only in LP
results.Dump();
this yields the rows 3, 4, 6, 7.
However: You only want the last occurence, not all, so you have to query results again:
results.Skip(Math.Max(0, results.Count() - 1)).Take(1);
Kind regards

EF Sum between 3 tables

Say we got a Database design like this.
Customer
Id Name
1 John
2 Jack
Order
Id CustomerId
1 1
2 1
3 2
OrderLine
Id OrderId ProductId Quantity
1 1 1 10
2 1 2 20
3 2 1 30
4 3 1 10
How would I create an entity framework query to calculate the total Quantity a given Customer has ordered of a given Product?
Input => CustomerId = 1 & ProductId = 1
Output => 40
This is what I got so far, through its not complete and still missing the Sum.
var db = new ShopTestEntities();
var orders = db.Orders;
var details = db.OrderDetails;
var query = orders.GroupJoin(details,
order => order.CustomerId,
detail => detail.ProductId,
(order, orderGroup) => new
{
CustomerID = order.CustomerId,
OrderCount = orderGroup.Count()
});
I find it's easier to use the special Linq syntax as opposed to the extension method style when I'm doing joins and groupings, so I hope you don't mind if I write it in that style.
This is the first approach that comes to mind for me:
int customerId = 1;
int productId = 1;
var query = from orderLine in db.OrderLines
join order in db.Orders on orderLine.OrderId equals order.Id
where order.CustomerId == customerId && orderLine.ProductId == productId
group orderLine by new { order.CustomerId, orderLine.ProductId } into grouped
select grouped.Sum(g => g.Quantity);
// The result will be null if there are no entries for the given product/customer.
int? quantitySum = query.SingleOrDefault();
I can't check what kind of SQL this will generate at the moment, but I think it should be something pretty reasonable. I did check that it gave the right result when using Linq To Objects.

LINQ grouping and ignoring column

I'm using EF and LINQ.
I have the following in my db table
branchId Name ItemId CategoryId
2 Test1 1 1
5 Test1 1 1
3 Test1 1 2
2 Test2 2 1
7 Test2 2 1
I need to group by ItemId and BranchId should be ignored, so the output should be
Name ItemId CategoryId
Test1 1 1
Test1 1 2
Test2 2 2
Please help. thanks
You need to apply group by which is on multiple column, so for that you need to go for code like as below which do group by on multiple columns....
var numberGroups = from it in context.items
group it by new { it.ItemId,it.Name,it.CateogryID } into g
select new { ItemID = g.Key.ItemID, Name= g.Key.Name
CategoryID = g.Key.CategoryID };
var query = from item in context.Item
group by item.Name,ItemId,item.CategoryId
select item.Name,Item.Id,item.CategoryId;

Categories