Group By Linq Issue - c#

I have a List of Items . The class looks like :
public class DeviceControllerDoorInfo
{
[DataMember]
public string DeviceControllerId { get; set; }
[DataMember]
public string DeviceControllerName { get; set; }
[DataMember]
public string DoorId { get; set; }
[DataMember]
public string DoorName { get; set; }
}
And the data looks like :
DoorId DoorName ControllerId ControllerName
------ -------- ------------ --------------
Door1 DoorOne C1 C1
Door2 DoorTwo C1 C1
Door3 DoorThree C2 C2
I want it to be converted , to look like it.
public class AccessGroupControllerDoorEntity
{
public string ControllerId { get; set; }
public string ControllerName { get; set; }
public List<AccessGroupDoorEnity> Doors { get; set; }
}
public class AccessGroupDoorEnity
{
public string DoorId { get; set; }
public string DoorName { get; set; }
}
Group By the ControllerId and then list the door items.
How to do it ?
I tried :
var controllersId = allDoors.GroupBy(e => e.DeviceControllerId).Select(x => x);
But does it make the Doors as List ?
I am not sure . Please help.
UPDATE
In my Data Service
private AccessGroupEntity ConvertDoorsToEntity(DeviceControllerDoorInfo[] allDoors)
{
// return null if the object is invalid.
if (allDoors != null)
{
AccessGroupEntity entity = new AccessGroupEntity();
entity.ControllerDoorItems = new List<AccessGroupControllerDoorEntity>();
//Convert to requested format instead of the below
foreach (var door in allDoors)
{
entity.DoorItems.Add(new DoorInfoEntity
{
DoorId = door.DoorId,
DoorName = door.DoorName,
ControllerId = door.DeviceControllerId,
ControllerName = door.DeviceControllerName
});
}
return entity;
But instead I want entity.ControllerDoorItems to contain like the below grouped data :
ControllerId -> C1
ControllerName -> C1
Doors -> 2 Objects

DoorId DoorName ControllerId ControllerName
------ -------- ------------ --------------
Door1 DoorOne C1 C1
Door2 DoorTwo C1 C1
Door3 DoorThree C2 C2
When you use GroupBy(e => e.ControllerId) It will Return two lists (for the above example), which the first list has two Items Where ControllerId is C1 and another list with one item that its ControllerId is C2.
So GroupBy returns Lists and not Items.
For your updated question:
List<AccessGroupControllerDoorEntity> grouped = allDoors.GroupBy(e => e.ControllerId)
.Select(group => new AccessGroupControllerDoorEntity
{
DeviceControllerId = group.Key.Id,
DeviceControllerName = group.Key.Name,
Doors = group.ToList()
});

You can try
var list= allDoors.GroupBy(x=>new {x.ControllerId ,Name=ControllerName},
(key, group) => new AccessGroupControllerDoorEntity
{
ControllerId=Key.ControllerId ,
ControllerName=Key.ControllerName,
Doors = group.ToList()
}))
.ToList();

Related

Combine values from 2 object lists based on on common variable

I have two lists: List a, List b
var a1= new A
{
Name = "XYZ",
Id = "123"
};
var a2= new A
{
Name = "UVW",
Id = "567"
};
var a = new List<A>()
{
a1,
a2
};
public class A
{
public string Name{ get; set; }
public string Id{ get; set; }
}
var b1= new B
{
Location = "US",
Id = "123"
};
var b2= new B
{
Location = "IN",
Id = "567"
};
var b = new List<B>()
{
b1,
b2
};
public class B
{
public string Location{ get; set; }
public string Id{ get; set; }
}
Notice that Id is common in both A and B classes. The final goal is to have a list that contains values of members from both A and B classes:
var output = new List<AB>()
{
ab1,
ab2
}
public class AB
{
public string Id{ get; set; }
public string Name { get; set; }
public string Location { get; set; }
}
Or update List a to include values from List b?
How would I do that in C#?
You could use Join to get common data based on Id and populate AB, like the following code :
var output = aList.Join(bList,
a => a.Id,
b => b.Id,
(a, b) => new AB
{
Id = a.Id,
Location = b.Location,
Name = a.Name
}).ToList();
Demo
foreach(var item in output)
{
Console.WriteLine($"Id:{item.Id}, Name : {item.Name}, Location:{item.Location}");
}
Result:
Id:123, Name : XYZ, Location:US
Id:567, Name : UVW, Location:IN
Demo in dotnetfiddle : https://dotnetfiddle.net/3ZbK6c
I hope you find this helpful.

Retrieve data from a linked table and display it in a view

I have two Models:
M1:
namespace wb01.Models
{
using System;
using System.Collections.Generic;
public partial class M1
{
public M1()
{
this.M2 = new HashSet<M2>();
}
public int Id { get; set; }
public int N° { get; set; }
public string Commentaires { get; set; }
public int Id_qualité { get; set; }
public virtual Qualité Qualité { get; set; } //*(Qualité est autre table dans ma BDD)
public virtual ICollection<M2> M2 { get; set; }
}
}
And a second Model M2:
namespace wb01.Models
{
using System;
using System.Collections.Generic;
public partial class M2
{
public int Id_M2 { get; set; }
public string N_wg { get; set; }
public double Poids { get; set; }
public int Id { get; set; }
public virtual M1 M1 { get; set; }
}
}
And a Controller:
namespace wb01.Controllers
{
using static wb01.Models.M2;
public class M1Controller : Controller
{
private M1Entities db = new M1Entities();
// GET: M1
public ActionResult Index()
{
var m1 = db.M1.Include(r => r.Qualité);
return View(m1.ToList());
}
}
}
I want in my View show the m1.ToList with a column contain the Poids of every Id in M1 (means for a m1_ID in M1 its Poids= sum(poids mi_ID in M2). Please if someone can help me ?
So maybe you can try to join your 2 tables:
public ActionResult Index()
{
var query = db.M1 // your starting point - table in the "from" statement
.Join(db.M2, // the source table of the inner join
t1 => t1.id, // Select the primary key (the first part of the "on" clause in an sql "join" statement)
t2 => t2.id, // Select the foreign key (the second part of the "on" clause)
(t1, t2) => new { t1 = t1, t2 = t2 }) // selection
.Where(M1AndM2 => M1AndM2.t1.id == 1); // where statement
return View(m1.ToList());
}
You can project on the columns you need like so
var m1 = db.M1.Include(r => r.M2).Include(r => r.Qualité).Select(r => new {
Poids = r.M2.Sum(x => x.Poids),
Col1 = r.Col1,
Col2 = r.Col2,
Col3 = r.Col3,
Col4 = r.Col4
});
return View(m1.ToList());

convert mvc c# model class to json from datatable

I have a C# class and data table.
DataTable:
+---------+-----------------+---------------+---------+---------+--------------+
| Pers_Id | Pers_First_Name | Pers_Last_Name| OrderNu | OrderId | Pers_Update |
+---------+-----------------+---------------+---------+---------+--------------+
| 1 | ABC | Ln | 76454 | 1 | 2018-03-25 |
+---------+-----------------+---------------+---------+---------+--------------+
| 1 | ABC | Ln | 76578 | 2 | 2018-03-25 |
+---------+-----------------+---------------+---------+---------+--------------+
Class:
public class Person
{
public int Pers_Id { get; set; }
public string Pers_First_Name { get; set; }
public string Pers_Last_Name { get; set; }
public DateTime Pers_Update { get; set; }
public List<Order> Order_List { get; set; }
public class Order
{
public int OrderID { get; set; }
public string OrderNu { get; set; }
}
}
I need to bind this class from data table and need to convert it into json object for rest API response in asp .net web API.
When i am binding i am getting json duplicate but result should be like this
{
"Pers_Id": 1,
"Pers_First_Name": "ABC",
"Pers_Last_Name": "LN",
"Pers_Update": "",
"Order_List": [
{
"OrderID": "1",
"OrderNu": "76454"
},
{
"OrderID": "2",
"OrderNu": "76578"
}
]
}
When you have an object (f.eks. your Employee object in this example), you should be able to return it like this:
return Content(JsonConvert.SerializeObject(employee), "application/json");
More info here: https://stackoverflow.com/a/34091196/4034346
First;
using System.Web.Script.Serialization;
Second;
If your data table's class isn't same with your Person class, then you should create a new class of datatable version for your persons.
public class Person
{
public int Pers_Id { get; set; }
public string Pers_First_Name { get; set; }
public string Pers_Last_Name { get; set; }
public DateTime Pers_Update { get; set; }
public List<Order> Order_List { get; set; }
public class Order
{
public int OrderID { get; set; }
public int OrderNu { get; set; }
}
}
//You need a class that fits to your DataTable
public class PersonDataTable
{
public int Pers_Id { get; set; }
public string Pers_First_Name { get; set; }
public string Pers_Last_Name { get; set; }
public DateTime Pers_Update { get; set; }
public int OrderId { get; set; }
public int OrderNu { get; set; }
}
In your method;
public string ReturnGoodPeopleJsonFormat()
{
JavaScriptSerializer js = new JavaScriptSerializer();//Needed for converting an object to Json string.
List<PersonDataTable> personDataTableList = new List<PersonDataTable>();//Needed for filling your data from in program or from database
List<Person> personList = new List<Person>();//Needed 'to be converted' in to Json string
//Add items to your DataTable list manually
personDataTableList.Add(
new PersonDataTable { Pers_Id = 1, Pers_First_Name = "ABC", Pers_Last_Name = "Ln", Pers_Update = Convert.ToDateTime("2018-03-25"), OrderId = 1, OrderNu = 76454 });
personDataTableList.Add(
new PersonDataTable { Pers_Id = 1, Pers_First_Name = "ABC", Pers_Last_Name = "Ln", Pers_Update = Convert.ToDateTime("2018-03-25"), OrderId = 2, OrderNu = 76578 });
//or from database
// personDataTableList.AddRange(myDatabaseModel.DataTables.ToList());
//Now group your data by Pers_Id //We are grouping this because we don't want same person 2 or 3 time, we want one person just one time but get all orders in it. That's why we need to group them by Pers_Id
foreach (var personGroup in personDataTableList.GroupBy(x => x.Pers_Id))
{
List<Person.Order> orderList = new List<Person.Order>();
foreach (var dataTablePerson in personDataTableList.Where(x => x.Pers_Id == personGroup.Key))
{
//Get all orders of personGroup one by one in to an Order list from PersonDataTable list by using Pers_Id like a foreign key.
///This personGroup.Key is nothing but Pers_Id\\\
orderList.Add(new Person.Order { OrderID = dataTablePerson.OrderId, OrderNu = dataTablePerson.OrderNu });
}
//Add new Person object to your personList if you don't have it before (by checking Pers_Id)
if (personList.Where(x => x.Pers_Id == personGroup.Key).Count() == 0) //This personGroup.Key is nothing but Pers_Id
{
personList.Add(new Person
{
Pers_Id = personDataTableList.Where(x => x.Pers_Id == personGroup.Key).FirstOrDefault().Pers_Id,
Pers_First_Name = personDataTableList.Where(x => x.Pers_Id == personGroup.Key).FirstOrDefault().Pers_First_Name,
Pers_Last_Name = personDataTableList.Where(x => x.Pers_Id == personGroup.Key).FirstOrDefault().Pers_Last_Name,
Pers_Update = personDataTableList.Where(x => x.Pers_Id == personGroup.Key).FirstOrDefault().Pers_Update,
Order_List = orderList
});
}
}
string JsonString = js.Serialize(personList);
return JsonString;
}
The result is like this:
[{"Pers_Id":1,"Pers_First_Name":"ABC","Pers_Last_Name":"Ln","Pers_Update":"/Date(1521925200000)/","Order_List":[{"OrderID":1,"OrderNu":76454},{"OrderID":2,"OrderNu":76578}]}]

Nest ignoring my percolate query property

I'm indexing a type that has percolate query but Nest/elasticsearch choose to ignore the query property.
public class MyQueryModel
{
public string Id { get; set; }
public string UserId { get; set;}
public string Email { get ; set;}
public string Name { get; set; }
public string State { get; set; }
public QueryContainer PercolatedQuery { get; set; }
}
public class DocModel
{
public string Id { get; set; }
public string Title { get; set; }
public string State { get; set; }
public string Category { get; set;}
public string Email { get; set; }
}
EDIT: some of property names between the 2 are same by coincidence. They totally mean different things on either of the 2 models and maybe mapped differently.
my mappings:
on queries index:
client.CreateIndex("on_my_queries", c => c
.Mappings(m => m
.Map<MyQueryModel>(mq => mq
.AutoMap()
.Properties(props => props
.Percolator(perc => perc
.Name(m => m.PercolatedQuery)
)
)
)
)
)
on doc index
client.CreateIndex("on_my_docs", c => c
.Mappings(m => m
.Map<MyDocModel>(md => md
.AutoMap()
)
)
)
Indexing my query model:
var queryModel = new MyQueryModel
{
Id = "some-id",
UserId = "some-user-id",
Email = "some-valid-email",
State = "some-valid-state",
PercolatedQuery = new TermQuery
{
Field = "category",
Value = "some-valid-cat-on-my-doc-models"
}
}
var request = new IndexRequest<QueryModel>(DocumentPath<MyQueryModel>.Id(queryModel));
var result = client.Index(request);
Everything gets indexed except the PercolatedQuery field. After scratching a lot of my head, I find out that client is not even serializing it. I ran the following only to see that PercolatedQuery was not serialized:
var jsonString = client.Serializer.SerializeToString(request);
jsonString:
{
"id" : "some-id",
"userId" : "some-user-id",
"email: : "some-valid-email",
"state" : "some-valid-state"
}
What client see as percolated query:
var queryString = client.Serializer.SerializeToString(queryModel.PercolatedQuery);
queryString:
{
"term": {
"category": {
"value": "some-valid-cat-on-my-doc-models"
}
}
}

Duplicate Insertion into database

I'm currently experiencing a funny issue here, each time I insert a new item with EntityFramework, I get to see a new Item submitted first before the real time but with the same entries(properties) and a String[] Array in the last column. I actually have a model defined thus
public class SupervisionStageSetupModel
{
public int Id { get; set; }
[Required]
public string StageLevel { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Description { get; set; }
public IList<SupervisionStageSetupChecklistModel> SupervisionStageSetupChecklists { get; set; }
public string GetAuditDetails(string action)
{
return string.Format("{0} SupervisionStageSetup Setup: {1}", action,Name);
}
}
public class SupervisionStageSetupChecklistModel
{
public int Id { get; set; }
public int SupervisionStageSetupId { get; set; }
public string Description { get; set; }
public string[] Options { get; set; }
}
And in my service, I have a method that does the insert operation as thus
private void ProcessCheckListItems(List<SupervisionStageSetupChecklist> entities,
IList<SupervisionStageSetupChecklistModel> checkListItems, int stageSetupId)
{
var modelIds = checkListItems.Select(x => x.Id).ToList();
var supervisionStageSetupChecklistRepository = _repository.GetRepository<SupervisionStageSetupChecklist>();
var entitiesToDelete =
entities.Where(x => !modelIds.Contains(x.Id));
entitiesToDelete.ForEach(x => supervisionStageSetupChecklistRepository.Delete(x));
var entitiesToAdd = checkListItems.Where(x => x.Id == 0).Select(x =>
new SupervisionStageSetupChecklist()
{
Description = x.Description,
SupervisionStageSetupId = stageSetupId,
Options = String.Join(",",x.Options)
}).ToList();
entitiesToAdd.ForEach(x =>
{
supervisionStageSetupChecklistRepository.Insert(x);
}
);
var entityToUpdate =
entities.Where(x => modelIds.Contains(x.Id));
entityToUpdate.ForEach(source =>
{
var checklistItem = checkListItems.Single(x => x.Id == source.Id);
source.Description = checklistItem.Description;
source.Options = String.Join(",",checklistItem.Options);
supervisionStageSetupChecklistRepository.Update(source);
});
When I put my VS2013 in debug mode to see what's happening, I saw that it was just only the number of items that came from the view that was inserted, but going back to my MSSQL2014 , I found two records inserted as
Id| SupervisionStageId | Description | Options
2 | 3 | Description | String[] Array
3 | 3 | Description | Yes,No
And of course, after setting breakpoint while inserting, I hovered on the entitiesToAdd object which returned 1 as the count, and this not enough, retrieving the item with the following ...
public SupervisionStageSetupItem GetDetails(int id)
{
var entity = _repository.Find(id);
var item = Mapper.Map<SupervisionStageSetup, SupervisionStageSetupItem>(entity);
item.SupervisionStageSetupChecklists =
entity.SupervisionStageSetupChecklists.Where(x => x.SupervisionStageSetupId == entity.Id)
.Select(x => new SupervisionStageSetupChecklistModel()
{
Description = x.Description,Options = x.Options.Split(',')
}).ToList();
return item;
}
I got the one Options property value as "Y","e","s",",","N","o".
I'm perplexed!, Don't know what I'm doing wrong

Categories

Resources