How to create a list dynamically from a class name (which is passed as argument) and return the list in c#.net - list

How to create a list dynamically from a class name (which is passed as an argument) and return the list in C#.
Below code may not work. I have posted it to give an idea:
public T ConvertDataSetToList<T>(DataSet _ds, String tableName, string className)
{
Type classType=Type.GetType(className);
List<T> newList = new List<T>();
//System.Activator.CreateInstance(Type.GetType(className));
try
{
Details _Details;
for (int iRowCount = 0; iRowCount < _ds.Tables[tableName].Rows.Count; iRowCount++)
{
_Details = FillDTO(_ds.Tables[tableName].Rows[iRowCount]);
newList.Add(_msDetails);
}
}
catch (Exception ex) { }
return newList;
}

You can dot it with some basic mapping stuff.
//Maps a dataset
public List<T> MapDataSet<T>(DataSet anyDataset
, string tablename) where T : new()
{
return MapDataTable<T>(anyDataset.Tables[tablename]);
}
// Maps a datatable
public List<T> MapDataTable<T>(DataTable table) where T : new()
{
List<T> result = new List<T>();
foreach(DataRow row in table.Rows)
{
result.Add(MapDataRow<T>(row));
}
return result;
}
// maps a DataRow to an arbitrary class (rudimentary)
public T MapDataRow<T>(DataRow row) where T: new()
{
// we map columns to class properties
Type destinationType = typeof(T);
// create our new class
T mappedTo = new T();
// iterate over the columns
for(int columnIndex=0;columnIndex<row.ItemArray.Length;columnIndex++)
{
// get a matching property of our class
PropertyInfo fieldTo = destinationType.GetProperty(
row.Table.Columns[columnIndex].ColumnName );
if (fieldTo !=null)
{
// map our fieldvalue to our property
fieldTo.SetValue(mappedTo, row[columnIndex], new object[] {});
}
else
{
// sorry, field doens't match any property on class
}
}
return mappedTo;
}
Here is basic test app to demonstrate its usage
void Main()
{
DataTable dt = new DataTable("hello");
dt.Columns.Add("foo");
dt.Columns.Add("bar");
dt.Columns.Add("foobar");
DataRow row = dt.NewRow();
row[0]="blah1";
row[1] ="two";
row[2] = "fb1";
dt.Rows.Add(row);
row = dt.NewRow();
row[0]="apples";
row[1] ="pears";
row[2] = "duh";
dt.Rows.Add(row);
List<DTO> list = MapDataTable<DTO>(dt);
List<SecondDTO> list2 = MapDataTable<SecondDTO>(dt);
}
// sample DTO object
public class DTO
{
public string foo { get; set;}
public string bar { get; set; }
}
// another sample DTO object
public class SecondDTO
{
public string foo { get; set;}
public string foobar { get; set; }
}

Related

How to access a list inside a class and return as a list of items in asp.netcore?

I have a class showbookings with salesinformation list.
public class ShowBookings
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string Id { get; set; }
public string ShowId { get; set; }
public DateTime ShowTime { get; set; }
public List<SalesInformation> SalesInformation { get; set; }
}
public class SalesInformation
{
public string SeatNo { get; set; }
public string SalesOrderConfirmationId { get; set; }
}
While calling update method I need to update for SeatNo and SalesOrderConfirmationId but this list is not accessible to me inside for loop.I need to return the list of items after updating showid,seatno SalesOrderConfirmationId but item.SalesInformation = salesInfo shows an error cannot convert salesinformation to generic list.Pls let me know how to sort this issue
public async Task<ActionResult<List<ShowBookings>>> UpdateShowBookings(string ShowId, string SeatNo, string SalesOrderConfirmationId)
{
var showBookings = new List<ShowBookings>();
var salesInformation = new List<SalesInformation>();
showBookings = await _context.DbCollection.Find(ShowBookings => ShowBookings.ShowId == ShowId)
.ToListAsync().ConfigureAwait(false);
if (showBookings != null)
{
var _sbList = showBookings.ToList();
foreach (var item in _sbList)
{
var salesInfo = new SalesInformation();
item.ShowId = ShowId;
salesInfo.SeatNo = SeatNo;
item.SalesInformation = salesInfo;
_sbList.Add(item);
}
return _sbList;
}
else
{
return new List<ShowBookings>();
}
}
"SalesInformation" is a list, while salesInfo is a object. You need to do:
item.SalesInformation.Add(salesInfo);
Also, in ShowBooking, inside constructor, initialize your List, else you will receive NullReferenceException.
Try to use
item.SalesInformation = new List<SalesInformation> { salesInfo };
SalesInformation of ShowBookings is List<SalesInformation> type,so you need to set its value with a list.
you already have list of showbookings
public async Task<ActionResult<List<ShowBookings>>> UpdateShowBookings(string ShowId, string SeatNo, string SalesOrderConfirmationId)
{
var salesInformation = new List<SalesInformation>();
var showBookings = await _context.DbCollection.Find(ShowBookings => ShowBookings.ShowId == ShowId)
.ToListAsync().ConfigureAwait(false);
if (showBookings != null)
{
return showBookings;
}
else
{
return new List<ShowBookings>();
}
}

Web Forms For Marketers (WFFM) Visual Fields for custom Field Type not displaying

I've used the following code to add two properties to Form Designer but they won't display. The field type is similar to Sitecore.Form.Web.UI.Controls.CheckboxList and I need it to display the same properties. Unfortunately I can't step into this code and the module isn't throwing any errors so I feel like I'm missing something simple.
public class CheckBoxListPipedField : Sitecore.Forms.Mvc.Models.Fields.CheckBoxListField
{
[VisualCategory("List")]
[VisualFieldType(typeof(Sitecore.Form.Core.Visual.ListField))]
[VisualProperty("Items:", 100)]
public ListItemCollection ListItems { get; set; }
[VisualCategory("List")]
[VisualFieldType(typeof(MultipleSelectedValueField))]
[VisualProperty("Selected Value:", 200)]
public ListItemCollection SelectedValue { get; set; }
public CheckBoxListPipedField(Item item) : base(item)
{
}
public override ControlResult GetResult()
{
var values = new List<string>();
StringBuilder stringBuilder1 = new StringBuilder();
if (this.Items != null)
{
foreach (SelectListItem selectListItem in
from item in this.Items
where item.Selected
select item)
{
values.Add(selectListItem.Value);
stringBuilder1.AppendFormat("{0}, ", selectListItem.Text);
}
}
var results = string.Join("|", values);
return new ControlResult(base.ID.ToString(), base.Title, results, stringBuilder1.ToString(0, (stringBuilder1.Length > 0 ? stringBuilder1.Length - 2 : 0)));
}
}
Not sure why they wouldn't show up as the default code for the CheckboxListField doesn't have those, but try:
[TypeConverter(typeof(ListSelectItemsConverter))]
public override List<SelectListItem> Items
{
get
{
return base.Items;
}
set
{
base.Items = value;
if (this.Items != null)
{
this.Value = (
from x in this.Items
where x.Selected
select x.Value).ToList<string>();
}
}
}
[ParameterName("selectedvalue")]
[PropertyBinder(typeof(ListFieldValueBinder))]
[TypeConverter(typeof(ListItemsConverter))]
public override object Value
{
get;
set;
}
You might be able to just set these to get { return base.Column }, etc, but here is how it looks on the base class.
[DefaultValue(1)]
public int Columns
{
get;
set;
}
[TypeConverter(typeof(StringToDirection))]
public Direction Direction
{
get;
set;
}
public int Rows
{
get
{
if (this.Items.IsNullOrEmpty<SelectListItem>())
{
return 1;
}
int num = (this.Columns == 0 ? 1 : this.Columns);
if (this.Items.Count % num <= 0)
{
return this.Items.Count / num;
}
return this.Items.Count / num + 1;
}
}
There was nothing wrong with the code in question. I neglected to add the assembly and class to the new Field Type, and had only set the MVC type.

Protobuf-net - list of objects with parent reference

I have a simple class with reference to parent object. All objects are in one list (even parent objects). Is it possible to keep references references after deserialization?
In my code I have something like this:
[ProtoContract]
public class ProtoItem
{
[ProtoMember(1)]
public int Value { get; set; }
[ProtoMember(2, AsReference = true)]
public ProtoItem BaseItem { get; set; }
}
And main looks like that:
static void Main()
{
var itemParent = new ProtoItem { Value = 1 };
var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };
var parentListToWrite = new List<ProtoItem> {itemParent, item2, item3};
const string file = "protofile.txt";
try { File.Delete(file); }
catch { };
using (var fs = File.OpenWrite(file)) { Serializer.Serialize(fs,
parentListToWrite); }
List<ProtoItem> readList;
using (var fs = File.OpenRead(file)) { readList =
Serializer.Deserialize<List<ProtoItem>>(fs); }
if (readList[0] == readList[2].BaseItem)
{
//how to make it equal?
}
if (readList[0] == readList[1].BaseItem)
{
//how to make it equal?
}
}
Is it possible to deserialize that if conditions works?
The protobuf specification doesn't have the notion of object identity. protobuf-net does (as an optionally enabled feature), but it doesn't currently work for list items directly, although I suspect it probably should. Since it would break the format, though, it would need explicit enabling if I fixed this.
But the following code works today - note that what I have done here is to wrap the top-level list items in a wrapper that just encapsulates the ProtoItem, but in doing so enables reference-tracking. Not ideal, but: it works.
using ProtoBuf;
using System.Collections.Generic;
using System.IO;
[ProtoContract(AsReferenceDefault=true)]
public class ProtoItem
{
[ProtoMember(1)]
public int Value { get; set; }
[ProtoMember(2)]
public ProtoItem BaseItem { get; set; }
}
[ProtoContract]
public class Wrapper
{
[ProtoMember(1, DataFormat = DataFormat.Group)]
public ProtoItem Item { get;set; }
public static implicit operator ProtoItem(Wrapper value)
{
return value == null ? null : value.Item;
}
public static implicit operator Wrapper(ProtoItem value)
{
return value == null ? null : new Wrapper { Item = value };
}
}
static class Program
{
static void Main()
{
var itemParent = new ProtoItem { Value = 1 };
var item2 = new ProtoItem { Value = 2, BaseItem = itemParent };
var item3 = new ProtoItem { Value = 3, BaseItem = itemParent };
var parentListToWrite = new List<Wrapper> { itemParent, item2, item3 };
const string file = "protofile.txt";
try
{ File.Delete(file); }
catch
{ };
using (var fs = File.OpenWrite(file))
{
Serializer.Serialize(fs,
parentListToWrite);
}
List<Wrapper> readList;
using (var fs = File.OpenRead(file))
{
readList = Serializer.Deserialize<List<Wrapper>>(fs);
}
if (readList[0].Item == readList[2].Item.BaseItem)
{
//how to make it equal?
System.Console.WriteLine("eq");
}
if (readList[0].Item == readList[1].Item.BaseItem)
{
//how to make it equal?
System.Console.WriteLine("eq");
}
}
}

How to get distinct records from a list

I have a list of type Myclass
List<Myclass> liSubjectIdDetail = new List<Myclass>();
where Myclass looks like
public class Myclass
{
public Nullable<decimal> SubjectId { get; set; }
public string SubjectName { get; set; }
}
I am adding records into liSubjectIdDetail from a table
foreach (decimal Id in VarCEMSIdDetail)
{
liSubjectIdDetail.AddRange(db.Stt.MyTable.Where(x => x.Id == Id).Select(x => new Myclass { SubjectId = x.SubjectId, SubjectName = x.SubjectName }).ToList());
}
where Id contains a list of certain Ids on the basis of which records I fetch.
Now I want to get only distinct records in this list.
I have tried it with hashtable in place of List
and I also tried
liSubjectIdDetail= liSubjectIdDetail.Distinct().ToList();
but this too, is not working. Please give me a better solution.
Thanks in advance
Try this extension method
public static class IEnumerableExtensions {
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
var seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
}
Usage:
liSubjectIdDetail= liSubjectIdDetail.DistinctBy(s => s.SubjectName).ToList();

How to set value of list<String> in DynamicJasper

I need to generate dynamic count of columns in me report. So I set to my JasperPrint the massive of Object:
Object[] obj = new Object[selectedUsers.size()];
//fill the massive
JasperPrint jp = DynamicJasperHelper.generateJasperPrint(dr, new ClassicLayoutManager(), new JRBeanArrayDataSource(obj));
My obj is a class:
public class ResultsDTO {
private String login;
private Integer id;
private List<String> list;
private Object[] results;
public Object[] getResults() {
return results;
}
public void setResults(Object[] results) {
this.results = results;
}
public ResultsDTO(){
}
public ResultsDTO(Integer id,String login) {
super();
this.login = login;
this.id = id;
}
public ResultsDTO(String login, Integer id, List<String> list) {
super();
this.login = login;
this.id = id;
this.list = list;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public void addToList(String day_result){
this.list.add(day_result);
}
}
and then I try to create columns:
FastReportBuilder firstReport = new FastReportBuilder();
List<AbstractColumn> column_list = new ArrayList<AbstractColumn>();
AbstractColumn columnId = getColumn("id", Integer.class,"№", 30, headerStyle, detailStyle);
AbstractColumn columnLogin = getColumn("login", String.class,"ФИО", 150, headerStyle, detailStyle);
for (int i = 0; i < header.size(); i++){
AbstractColumn column = getColumn("results", Object.class, header.get(i), 80, headerStyle, detailStyle);
column_list.add(column);
}
Eventually I have an exception:
net.sf.jasperreports.engine.design.JRValidationException: Report
design not valid :
1. Class "java.lang.Object" not supported for text field expression.
Please, help! I don' know how to use jasper and list or array
Jasper Reports does not allow Object as a valid type for its elements. I has to be one of the following:
String
Number (or any subclass of it)
Date
Boolean
You should ask each element in the form for its class and pass proper class to the column builder.