How to segregate data into different buckets using LINQ in VB.NET? - vb.net

I am new to VB.NET and can't find a way to segregate data into different buckets using LINQ in VB.NET ?
I have a list of objects and based on a particular property, I want to divide it based on distinct values for the property.
Edit:
static void Main(string[] args)
{
List<DemoClass> ListDemoClass = new List<DemoClass>();
DemoClass demo1 = new DemoClass();
demo1.city = "Pune";
demo1.name = "Pranav";
ListDemoClass.Add(demo1);
DemoClass demo2 = new DemoClass();
demo1.city = "Pune";
demo1.name = "Brij";
ListDemoClass.Add(demo2);
DemoClass demo3 = new DemoClass();
demo1.city = "Pune";
demo1.name = "Piyush";
ListDemoClass.Add(demo3);
DemoClass demo4 = new DemoClass();
demo1.city = "NJ";
demo1.name = "Igal";
ListDemoClass.Add(demo4);
DemoClass demo5 = new DemoClass();
demo1.city = "NJ";
demo1.name = "Mithun";
ListDemoClass.Add(demo5);
List<List<DemoClass>> buckets = ListDemoClass
.GroupBy(x => x.city)
.Select(grp => grp.ToList())
.ToList();
}
Expected output is a list containing two lists of 2 and 3 objects respectively based on the city.
However this is not working. The result is I have a list of list of 1 and 4 items, which comes to be wrong. In the second list ,the objects are null.

The question is pretty unclear but maybe this helps anyway, use Enumerable.GroupBy:
VB:
Dim buckets As List(Of List(Of ClassName)) = list.
GroupBy(Function(x) x.PropertyName).
Select(Function(grp) grp.ToList()).
ToList()
C#
List<List<ClassName>> buckets = list
.GroupBy(x => x.PropertyName)
.Select(grp => grp.ToList())
.ToList();
Your demo code only initializes demo1 properties not the other objects.

You can use something like:
Dim result As List(Of List(Of SomeType)) = list.GrouBy(Function(x) x.Property).Select(Function(x) x.ToList()).ToList()
In C#, you would group the items to a list of lists in the following way:
List<List<SomeType>> result = list.GrouBy(x => x.Property).Select(x => x.ToList()).ToList();

Related

List of array object iteration in java 8

I am setting the type for sql query result set as List in java. I am trying to convert it into
a dto.
When I see the List<Object[]> structure from query. It shows
resultList-ArrayList<E>
[0....9999]
[0..99]
[0]=Object[3]
[0]="jjj"
[1]="8787"
[2]="7686"
So is this expected. How can I access the object values here(jjj,8787...) by setting it to dto.
I tried something like this
List<Dto> dtoList = resultList.stream().map(obj->{
Dto dt = new Dto()
dt.setName(obj[0]);
).collect(Collectors.toList())
This is not correct as I am not able to access the object
Should I do another level of iteration in order to reach that object or is my generic type for result set is right
Thanks
Try this:
Object[] inner = new Object[]{"jjj", "8787", "7686"};
Object[] outer = new Object[]{inner};
List<Object[]> resultList = new ArrayList<>();
resultList.add(outer);
List<Dto> dtos;
dtos = resultList.stream()
.flatMap((Object[] objArr) -> {
Object[] subArr = (Object[]) objArr[0];
return Arrays.asList(subArr).stream()
.map(obj -> obj.toString());
})
.map(name -> {
Dto dto = new Dto();
dto.setName(name);
return dto;
})
.collect(Collectors.toList());

Convert a Linq result to a datatable

I am trying to convert a Linq result in to a datatable
I have a linq that is created from a dataset of many tables. It returns results, but I need to get the results in to a new datatable.
Examples I have seen say I sould be able to use .CopyToDataTable But for some reason this doesn't work?
I have noticed that I can to .ToArray perhaps I can then turn the array in to a datatable? Seems line an unnecessary step?
Here is my query: (it works)
Dim R2 = From Inq In DS.Tables!CNLocalInquiry.AsEnumerable()
Join Cust In DS.Tables!CustomerID.AsEnumerable() On Inq.Field(Of Integer)("CNLocalInquiry_Id") Equals Cust.Field(Of Integer)("CNLocalInquiry_Id")
Select New With {.date = Inq.Field(Of String)("date"),
.CName = Cust.Field(Of String)("CustomerNumber"),
.Name = Cust.Field(Of String)("name")}
Dim MemberInq as new datatable
MemberInq = R2.CopyToDataTable() <-- this doesn't work
This is what my query returns:
(this is the easy to code way... this will not be performant for large datasets)
public static class ToolsEx
{
public static DataTable ToDataTable<T>(this IEnumerable<T> items)
{
var t = typeof(T);
var dt = new DataTable(t.Name);
var props = t.GetProperties()
.Select(p => new { N = p.Name, Getter = p.GetGetMethod() })
.Where(p => p.Getter != null)
.ToList();
props.ForEach(p => dt.Columns.Add(p.N));
foreach (var item in items)
dt.Rows.Add(props.Select(p => p.Getter.Invoke(item, null)).ToArray());
return dt;
}
}
I've saved this as an extension method and it's always worked perfectly:
https://msdn.microsoft.com/en-us/library/bb669096.aspx
Examples here:
https://msdn.microsoft.com/en-us/library/bb386921.aspx
Hope that does the trick!

Entity framework - Return to list error?

I got the problem - return to list from the entity framework. I need to return as a object. Here is my code:
Public Function GetHardwareDetail() As List(Of HardwareDetailApp)
Dim idList As New List(Of String)
Dim Data = (From p In DB.TT_HARDWARE Select New HardwareDetailApp With {.InternalNum = p.INTERNAL_NUM, .Description = p.DESCRIPTION, .TerminalModel = p.HARDWARE_MODEL, .HardwareInternalNum = p.HARDWARE_ID, .Status = p.ISACTIVE, .Firmware = Nothing, .SerialNum = Nothing})
If Data.Count > 0 Then
For Each row In Data
idList.Add(row.InternalNum)
Next
End If
Dim Data2 = (From p In DB.TT_TERMINAL_HARDWARE Where idList.Contains(p.HARDWARE_INTERNAL_NUM)
Select New HardwareDetailApp With
{.Firmware = p.HARDWARE_FIRMWARE, .SerialNum = p.HARDWARE_SERIAL_NUM, .InternalNum = Data.FirstOrDefault.InternalNum, .Description = Data.FirstOrDefault.Description, .TerminalModel = Data.FirstOrDefault.TerminalModel, .HardwareInternalNum = Data.FirstOrDefault.HardwareInternalNum, .Status = Data.FirstOrDefault.Status})
Return Data2.ToList
End Function
This is the error which I get:
The type 'HardwareDetailApp' appears in two
structurally incompatible initializations within a single LINQ to
Entities query. A type can be initialized in two places in the same
query, but only if the same properties are set in both places and
those properties are set in the same order.
in your code, you have created from HardwareDetailApp in two place, in every creation of that you must set the same property with same order.
for example if in linq to entity you Select something like:
Place1:
...
Select new MyClass()
{
PropA: 1,
}
...
and in that query you need to another Select from MyClass but with some other properties like PropB, Like:
Place2:
...
Select new MyClass()
{
PropB: 2,
}
...
you must change all Select from MyClass into same, and set the properties you dont need to them, to its default, and set the properties in same order like:
Place1:
...
Select new MyClass()
{
PropA: 1,
PropB: default(int),
}
...
and
Place2:
...
Select new MyClass()
{
PropA: default(int),
PropB: 2,
}
...
my codes are in c#..
in this part of your code Dim Data = (From p In DB.TT_HARDW .... try to set Firmware and SerialNum at first like the second select, (i have not checked other properties carefully)

How to get the datatype of column from the sharepoint list?

I want to get or retrieve the datatype of a particular column where
the list is created in a sharepoint list.
Can you help me for doing the task?
See SPField.Type (or SPField.TypeDisplayName).
SPList list = web.Lists["my list"];
SPField field = list.Fields["particular"];
SPFieldType fieldType = field.Type;
string fieldTypeName = field.TypeDisplayName;
Building off of Rich Bennema's answer (referencing the Microsoft.SharePoint.Client and Microsoft.SharePoint.Client.RunTime version 16 libriaries and using the Microsoft.SharePoint.Client name space):
using (ClientContext cont = new ClientContext(SharePointUrl))
{
cont.Credentials = new SharePointOnlineCredentials(Username, SecurePassword);
FieldCollection fields = cont.Web.Lists.GetByTitle(SharePointListName).Fields;
cont.Load(fields);
cont.ExecuteQuery();
var results =
fields.Select(
f => new
{
f.InternalName,
f.TypeDisplayName,
TextMaxLength = (f is FieldText) ? ((FieldText)f).MaxLength : 0,
FieldChoices = (f is FieldChoice) ? ((FieldChoice)f).Choices : new string[0]
}
);
}

How do I return the column names of a LINQ entity

I am using LINQ to SQL queries to return data in my application. However I find it is now needful for me to return the column Names. Try as I might I have been completely unable to find out how to do this on the internet.
So if my LINQ entity table has the properties (Last_Name, First_name, Middle_Name) I need to return:
Last_name
First_Name
Middle_name
rather than the usual
Smith
John
Joe
You could certainly do it with some LINQ-To-Xml directly against the ".edmx" file or the embedded model resources in the compiled assembly.
The below query gets the field (not column) names. If you need the columns then just change the query to suit.
var edmxNS = XNamespace.Get(#"http://schemas.microsoft.com/ado/2007/06/edmx");
var schemaNS = XNamespace.Get(#"http://schemas.microsoft.com/ado/2006/04/edm");
var xd = XDocument.Load(#"{path}\Model.edmx");
var fields =
from e in xd
.Elements(edmxNS + "Edmx")
.Elements(edmxNS + "Runtime")
.Elements(edmxNS + "ConceptualModels")
.Elements(schemaNS + "Schema")
.Elements(schemaNS + "EntityType")
from p in e
.Elements(schemaNS + "Property")
select new
{
Entity = e.Attribute("Name").Value,
Member = p.Attribute("Name").Value,
Type = p.Attribute("Type").Value,
Nullable = bool.Parse(p.Attribute("Nullable").Value),
};
Lets assume you're talking about the Contact Table in the assembly named YourAssembly in a Context called MyDataContext
Using Reflection against a Table
You can use reflection to get the properties like you would any type
var properties = from property in
Type.GetType("YourAssembly.Contact").GetProperties()
select property.Name
;
foreach (var property in properties)
Console.WriteLine(property);
As shaunmartin notes this will return all properties not just Column Mapped ones. It should also be noted that this will return Public properties only. You'd need to include a BindingFlags value for the bindingAttr Parameter of GetProperties to get non-public properties
Using the Meta Model
You can use the Meta Model System.Data.Linq.Mapping to get the fields ( I added IsPersistant to only get the Column Mapped properties)
AttributeMappingSource mappping = new System.Data.Linq.Mapping.AttributeMappingSource();
var model = mappping.GetModel(typeof (MyDataContext));
var table = model.GetTable(typeof (Contact));
var qFields= from fields in table.RowType.DataMembers
where fields.IsPersistent == true
select fields;
foreach (var field in qFields)
Console.WriteLine(field.Name);
Using Reflection from a query result
If on the other hand you wanted it from a query result you can still use reflection.
MyDataContextdc = new MyDataContext();
Table<Contact> contacts = dc.GetTable<Contact>();
var q = from c in contacts
select new
{
c.FirstName,
c.LastName
};
var columns = q.First();
var properties = (from property in columns.GetType().GetProperties()
select property.Name).ToList();
I stumbled upon this answer to solve my own problem and used Conrad Frix 's answer. The question specified VB.NET though and that is what I program in. Here are Conrad's answers in VB.NET (they may not be a perfect translation, but they work):
Example 1
Dim PropertyNames1 = From Prprt In Type.GetType("LocalDB.tlbMeter").GetProperties()
Select Prprt.Name
Example 2
Dim LocalDB2 As New LocalDBDataContext
Dim bsmappping As New System.Data.Linq.Mapping.AttributeMappingSource()
Dim bsmodel = bsmappping.GetModel(LocalDB2.GetType())
Dim bstable = bsmodel.GetTable(LocalDB.tblMeters.GetType())
Dim PropertyNames2 As IQueryable(Of String) = From fields In bstable.RowType.DataMembers
Where fields.IsPersistent = True
Select fields.Member.Name 'IsPersistant to only get the Column Mapped properties
Example 3
Dim LocalDB3 As New LocalDBDataContext
Dim qMeters = From mtr In LocalDB3.tblMeters
Select mtr
Dim FirstResult As tblMeter = qMeters.First()
Dim PropertyNames3 As List(Of String) = From FN In FirstResult.GetType().GetProperties()
Select FN.Name.ToList()
To display the results:
For Each FieldName In PropertyNames1
Console.WriteLine(FieldName)
Next
For Each FieldName In PropertyNames2
Console.WriteLine(FieldName)
Next
For Each FieldName In PropertyNames3
Console.WriteLine(FieldName)
Next
Please also read Conrad's answer for notes on each method!