How to get the complex field data in class using Reflection (C#) - c#

I have a class as below
public class Orders
{
public Orders()
{
}
public Orders(long OrderId, string CustomerId,
int EmployeeId, double Freight, Info emp)
{
this.OrderID = OrderId;
this.CustomerID = CustomerId;
this.EmployeeID = EmployeeId;
this.Freight = Freight;
this.Employee = emp;
}
public long OrderID { get; set; }
public string CustomerID { get; set; }
public int EmployeeID { get; set; }
public double Freight { get; set; }
public Info Employee { get; set; }
}
public class Info
{
public string Address { get; set; }
public Info(string Add) {
this.Address = Add;
}
}
To extract the values i am doing as below.
public IEnumerable PerformFiltering(
IEnumerable dataSource, List<FilteredColumn> filteredColumns)
{
var paramExpression = dataSource.AsQueryable().Parameter();
Type type = dataSource.GetElementType();
if (type == null)
{
Type type1 = dataSource.GetType();
type = type1.GetElementType();
}
Type t = typeof(object);
foreach (var filteredColumn in filteredColumns)
{
Syncfusion.Linq.FilterType filterType = (Syncfusion.Linq.FilterType)Enum.Parse(
typeof(Syncfusion.Linq.FilterType),
filteredColumn.Operator.ToString(), true);
t = type.GetProperty(filteredColumn.Field).PropertyType;
Type underlyingType = Nullable.GetUnderlyingType(t);
}
}
I got the error
An exception of type 'System.NullReferenceException' occurred in Syncfusion.EJ.dll but was not handled in user code

Related

Create usinig linq object in linst by generic Type

I rewrote method and now we read data from .xlsx not json but I don't know how return IEnumerable .
Orginal code
private IEnumerable<TEntity> GetChild(string path)
{
var klasser = DeserializeJsonFile<IEnumerable<ParentFromJson>>(path)
.SelectMany(parent => parent.UnderClass.Select(klasse => new TEntity
{
Uuid = class.Uuid,
Name= class.Name,
Titel = class.Titel,
Number= class.Number,
Manual = class.Manual,
Parent = class.Parent
}));
return klasser;
}
and my try
var dataList = (from DataRow dr in resultTable.Rows
select new ParentFromJson().UnderClass.Select(x => new TEntity {
Uuid = x.Uuid,
Name= x.BrugervendtNoegle,
Titel = x.Titel,
Udgaaet = x.Udgaaet,
Number= x.DisallowManual,
Parent = x.Parent
}).FirstOrDefault());
Model.I don't know how put object in UnderClass list when I read from datatable
private class ParentFromJson
{
public IEnumerable<ChildFromJson> UnderClass{ get; set; }
}
private class ChildFromJson
{
public string Uuid { get; set; }
public string Name{ get; set; }
public string Titel { get; set; }
public bool Number{ get; set; }
public bool Manual { get; set; }
public string Parent { get; set; }
}

Getting and setting the value of nested properties

I have these classes
public class Employee
{
public int ID { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
}
public class Flat
{
public int ID { get; set; }
public string Name { get; set; }
public virtual Address Address { get; set; }
}
This is the code I am using to set the values on Flat class
var employee = new Employee() { ID = 1, Name = "Test", Address = new Address() {Line1 = "1", Line2 = "2" } };
Flat flat = new Flat();
Map(employee, flat);
static void Map<TI, VI>(TI source, VI result)
{
foreach (PropertyInfo item source.GetType().GetRuntimeProperties())
{
if (item.GetValue(source) != null)
{
if (result.GetType().GetRuntimeProperty(item.Name) != null)
{
Type type = result.GetType().GetRuntimeProperty(item.Name).PropertyType;
var innerObj = FormatterServices.GetUninitializedObject(type);
result.GetType().GetRuntimeProperty(item.Name).SetValue(result, innerObj);
Map(item.GetValue(source), innerObj);
}
else
{
Map(item.GetValue(source), result);
}
}
}
}
}
I would really appreciate if you could advise me if this is the right approach to map the nested properties. If this is not the case please provide alternatives.

Entity Framework Error - The cast to value type 'System.Int64' failed because the materialized value is null

The below method fails when Execting ToListAsync() with the following error
The cast to value type 'System.Int64' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
--
private IQueryable<MaterialSearchResult> MaterialSearchQuery(string searchTerm)
{
return from m in this.context.GB_Material
from v in this.context.WF_VideoVersion
.Where(
v =>
v.MaterialID == m.MaterialID)
.DefaultIfEmpty()
select new MaterialSearchResult
{
MaterialId = v.MaterialID,
MaterialName = v.GB_Material.MaterialName,
MaterialTitle = v.GB_Material.MaterialTitle,
CreatedDate = v.GB_Material.CreatedDate,
NearestTxDate = v.NearestTXDate,
Channel = v.ScheduleName
};
}
Calling method
public Task<List<MaterialSearchResult>> SearchMaterials(string searchTerm, string sort, string direction, int pageSize = 20, int skip = 0)
{
var data = MaterialSearchQuery(searchTerm)
.SortMaterials(sort,direction)
.Skip(skip)
.Take(pageSize);
return data.ToListAsync();
}
public class MaterialSearchResult
{
public long MaterialId { get; set; }
public string MaterialName { get; set; }
public string MaterialTitle { get; set; }
public DateTime? NearestTxDate { get; set; }
public string Channel { get; set; }
public DateTime CreatedDate { get; set; }
}
public class GB_Material()
{
public long MaterialID { get; set; }
public string MaterialName { get; set; }
public string MaterialTitle { get; set; }
public System.DateTime CreatedDate { get; set; }
public virtual ICollection<WF_VideoVersion> WF_VideoVersion { get; set; }
}
public class WF_VideoVersion()
{
public long VideoVersionID { get; set; }
public long MaterialID { get; set; }
public Nullable<System.DateTime> NearestTXDate { get; set; }
public string ScheduleName { get; set; }
public virtual GB_Material GB_Material { get; set; }
}
EDIT:
I'm also getting the same error on the NearestTxDate property
The cast to value type 'System.DateTime' failed because the materialized value is null.
Try to rewrite your query:
return from m in this.context.GB_Material
from v in this.context.WF_VideoVersion
.Where(
v =>
v.MaterialID == m.MaterialID)
.DefaultIfEmpty()
select new MaterialSearchResult
{
MaterialId = m.MaterialID,
MaterialName = m.MaterialName,
MaterialTitle = m.MaterialTitle,
CreatedDate = m.CreatedDate,
NearestTxDate = v.NearestTXDate,
Channel = v.ScheduleName
};
For some insane reason i had written the select statement like this:
select new MaterialSearchResult
{
MaterialId = v.MaterialID,
MaterialName = v.GB_Material.MaterialName,
MaterialTitle = v.GB_Material.MaterialTitle,
CreatedDate = v.GB_Material.CreatedDate,
NearestTxDate = v.NearestTXDate,
Channel = v.ScheduleName
}
WHen it should have been this
select new MaterialSearchResult
{
MaterialId = mMaterialID,
MaterialName = m.MaterialName,
MaterialTitle = m.MaterialTitle,
CreatedDate = m.CreatedDate,
NearestTxDate = v.NearestTXDate,
Channel = v.ScheduleName
}
Given that for some results the child would be null, then obviously going through the child to get the parents properties is not going to work.
I'm goin to blame it on a pre-lunch brain fart.

Constructor with argument :Missing return int value

I have class which contains many properties:
public class Report
{
public int reportId { get; set; }
public string sentDate { get; set; }
public string photoName { get; set; }
public string state { get; set; }
public string patientName { get; set; }
public string doctorName { get; set; }
public string sex { get; set; }
public int isPregnant { get; set; }
public float weight { get; set; }
public float height { get; set; }
public int age { get; set; }
public string information { get; set; }
public string response { get; set; }
then I implement one constructor with argmuents :
public Report(int id, string photoName, string sentDate, string state,string response)
{
this.reportId = id;
this.photoName = photoName;
this.sentDate = sentDate;
this.state = state;
this.response = response;
}
finally I implement method which calls this constructor :
public static List<Report> GetListReportByEmail(string email)
{
DataTable dt = SqlHelper.ExecuteDataset(
new SqlConnection(Tls.ConnStr),
"spReportGetByEmail",
email).Tables[0];
List<Report> tempItems = new List<Report>();
if (dt.Rows.Count != 0)
{
foreach (DataRow rw in dt.Rows)
{
tempItems.Add(
new Report(
int.Parse(rw["ReportId"].ToString()),
Tls.GetBasicUrl() + "/Zdnn000kjUpload/__zd__MedicalConsultation/"
+ rw["PhotoName"].ToString(),
DateTime.Parse(rw["SentDate"].ToString()).ToString("dd/M/yyyy"),
rw["State"].ToString(),
rw["Response"].ToString()));
}
return tempItems;
}
else
{
return null;
}
}
but when I check the return, in addition of the properties mentionned in the constructor I found all properties which its type is int or float with the value 0.
I need this methods for a web services. when I test this web serives I found properties mentionned in the constructor ,but also int and float which are not populated:
<Report>
<reportId>4</reportId>
<sentDate>21/6/2014</sentDate>
<photoName>
http://localhost:2055/Zdnn000kjUpload/__zd__MedicalConsultation/
</photoName>
<state/>
<isPregnant>0</isPregnant>
<weight>0</weight>
<height>0</height>
<age>0</age>
<response/>
</Report>
Knowing that the stored procedure is ok.
So can any one help me to transmit only variables mentionned in the constructor : I don't need age,height,weight,isPregnant to be transmitted
Thanks.
Your constructor only assigns the following:
this.reportId = id;
this.photoName = photoName;
this.sentDate = sentDate;
this.state = state;
this.response = response;
Why would you expect the other properties (isPregnant, weight, height, age, etc.) to be populated as well? You are not assigning those properties value at any point.

Set Properties within base function and call function in child function inheritance

I am trying to refactor some old code and wanted to create more logical inheritance.
We have struct Custom Class which we have separated into (3) levels:
AccountView > Details > Full with inheritance. We set the properties of each one as needed.
After looking at the setters, we wanted to combine them into a single class 'SetAccountProp' with methods that set the properties.
We have the 'CustomerBaseView' where we pass in Models ACCOUNT data which works.
Now for the CustomerDetailView pass the same Model ACCOUNT data, but we would like to fill the properties of 'CustomerBaseView' use function 'CustomerBaseView' then fill the details.
Also, for CustomerFullView pass the Model ACCOUNT data, and fill the properties of 'CustomerBaseView' THEN 'CustomerBaseView' and then the remaining fields for CustomerFullView.
How can I call and fill the 'CustomerBaseView' within the 'CustomerDetailView' function? Do I initialize new AccountsView(); in each function?
Not sure how to finish up the refactor without repeating the:
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
in the Details and Full functions.
CODE
namespace BLL.Presenters
{
public class AccountsView
{
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Details : AccountsView
{
public bool Administrator { get; set; }
public DateTime? LastLogin { get; set; }
}
public class Full : Details
{
public Guid ID { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public string FullName { get; set; }
}
public class SetAccountProp
{
public static AccountsView CustomerBaseView(Account data)
{
var view = new AccountsView();
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
return view;
}
public static Details CustomerDetailView(Account data)
{
var view = new Details();
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
// -- Details
view.Administrator = data.Administrator;
view.LastLogin = data.LastLogin;
return view;
}
public static Full CustomerFullView(Account data)
{
var view = new Full();
// -- CustomView <--- replace with func?
view.Email = data.Email;
view.Active = data.Active;
view.FirstName = data.FirstName;
view.LastName = data.LastName;
// -- Details <--- replace with func?
view.Administrator = data.Administrator;
view.LastLogin = data.LastLogin;
// -- Full
view.ID = data.ID;
view.Created = data.Created;
view.Modified = data.Modified;
view.FullName = data.LastName + ", " + data.FirstName;
return view;
}
}
}
Using constructor chaining, you could have something like this:
Each constructor calls it's base class' constructor first, so you don't have to repeat code.
namespace BLL.Presenters
{
using System;
public class Account // dummy to make it compile
{
public string Email;
public bool Active;
public string FirstName;
public string LastName;
public bool Administrator;
public DateTime? LastLogin;
public Guid ID;
public DateTime Created;
public DateTime Modified;
}
public class AccountsView
{
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public AccountsView(Account data)
{
this.Email = data.Email;
this.Active = data.Active;
this.FirstName = data.FirstName;
this.LastName = data.LastName;
}
}
public class Details : AccountsView
{
public bool Administrator { get; set; }
public DateTime? LastLogin { get; set; }
public Details(Account data) : base(data)
{
this.Administrator = data.Administrator;
this.LastLogin = data.LastLogin;
}
}
public class Full : Details
{
public Guid ID { get; set; }
public DateTime Created { get; set; }
public DateTime Modified { get; set; }
public string FullName { get; set; }
public Full(Account data) : base(data)
{
this.ID = data.ID;
this.Created = data.Created;
this.Modified = data.Modified;
this.FullName = data.LastName + ", " + data.FirstName;
}
}
class Program
{
static void Main()
{
Console.WriteLine();
Console.ReadLine();
}
}
}
Why not something like this:
public class CustomerBase
{
public string Email { get; private set; }
public bool Active { get; private set; }
public string FirstName { get; private set; }
public string LastName { get; private set; }
protected void SetAccountInfo(Account account)
{
this.Email = account.Email;
this.Active = account.Active;
this.FirstName = account.FirstName;
this.LastName = account.LastName;
}
}
public class CustomerA : CustomerBase
{
public string IsAdmin { get; private set; }
public DateTime? LastLogin { get; private set; }
public void SetAccountInfo(Account account)
{
base.SetAccountInfo(account);
this.IsAdmin = account.IsAdmin;
this.LastLogin = account.LastLogin;
}
}
public class Account
{
//your properties
public string Email { get; set; }
public bool Active { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string IsAdmin { get; set; }
public DateTime? LastLogin { get; set; }
}
Or let the SetAccountInfo() return this
public CustomerA SetAccountInfo(Account account)
{
base.SetAccountInfo(account);
this.IsAdmin = account.IsAdmin;
this.LastLogin = account.LastLogin;
return this;
}

Categories

Resources