C# Object List Initialization - c#

I have the class below
public class UserClient
{
public int client_id { get; set; }
public Icollection<ClassA> ACollections { get; set; }
public UserClient()
{
ACollections = new Icollection<ClassA>();
}
public class ClassA
{
public string Name { get; set; }
public Icollection<ClassB> BCollections { get; set; }
public ClassA()
{
BCollections = new Icollection<ClassB>();
}
public class ClassB
{
public ClassA ClassA { get; set; }
public Icollection<ClassC> CCollections { get; set; }
public ClassB()
{
CCollections = new Icollection<ClassC>();
}
public class ClassC
{
public ClassB ClassB { get; set;}
}
The three classes fetch and store related data from DB using entity framework and graphql and store the data in an object list that appears on the blazor client in the following JSON format
JSON FORMAT AFTER FETCH
{
public List<UserClient> allData = new List<UserClient>();
// Console.WriteLine(results.Data.ClientData.ToList());
allData = results.Data.ClientData.Select(x => new UserClient
{
client_id = x.Client_id,
ClassA = // <-- this is the point where I Have a problem
}).ToList();
I have difficulties assinging the contents of the second level, third level objects on the list created.

Related

Cast IQueryable generic to another IQueryable generic

I would like to have a common class for my business layers (BL) which has a method convert IQueryable to IQueryable.
- efo: Entity Framework object
- bo: business object
I'm using Entity Framework Core.
public partial class Language //EF object
{
public long Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public string Image { get; set; }
public virtual ICollection<News> News { get; set; }
}
public class BOLanguage //Business object
{
public string Name { get; set; }
public string Image { get; set; }
}
public class BL<efo, bo>
where efo : class, new()
where bo : class, new()
{
public Context context;
public BL()
{
context = new Context();
}
public IQueryable<bo> SelectAll()
{
IQueryable<efo> query = context.Set<efo>();
return query.Select(x => new bo
{
//TODO: I don't know how to do here
});;
}
//public IQueryable<BOLanguage> SelectAll() //example
//{
// return context.Language.Select(x => new BOLanguage
// {
// Name = x.Name,
// Image = x.Image
// });
//}
}
Thank you. Hope you understand.

Update list values after update root class object

I have the following classes:
public class Class_A
{
public string my_field { get; set; }
public int id { get; set; }
// etc...
}
public class Class_B
{
public string my_field { get; set; }
public Class_A field_A { get; set; }
// etc...
}
public class Class_C
{
public string my_field { get; set; }
public Class_A field_A { get; set; }
// etc...
}
List<Class_A> list_A = new List<Class_A>(); //and then populate it
List<Class_B> list_B = new List<Class_B>(); //and then populate it
List<Class_C> list_C = new List<Class_C>(); //and then populate it
And then, when I update some element of list_A, for example
Class_A old_a, new_a;
old_a = list_A.Where("some condition").FirstOrDefault();
new_a = new Class_A();//and then initialize it
list_A[list_A.FindIndex(x => x.Equals(old_a))] = new_a;
I need, that all elements of list_B and list_C, which field Class_A equals old_a will be update to new_a.
1. What is the best way to do this? Now I have following variant, but I think, that it's could be better:
list_B.Where(x => x.Class_A.Equals(old_a)).ForEach(x => x.Class_A = new_a);
2. What is the best way to update all values, if I'll have this code?
public class Class_D
{
public string my_field { get; set; }
public List<Class_A> list_A { get; set; }
// etc...
}
List<Class_D> list_D = new List<Class_D>(); //and then populate it
Have a look at ObservableCollection and Item PropertyChanged
You can make from your list_A an observable collection when can be received by Class_B and Class_C.

Ignore Mapping of inner list property in AutoMapper --EF6,C#

I have a collection property of DTO like this
public ICollection<Applicant> Applicants{get;set;}
Applicant Model
public class Applicant
{
public int Id{get;set;}
public string name{get;set;}
public ICollection<ApplicantSkillsVM> ApplicantSkills { get; set; }
}
public class ApplicantSkillsVM
{
public int Id {get;set;}
public Skill skill{get;set;}
}
I want to map my List<iApplicant> DTO to entity given that I want to take ApplicantSkillsVM but ignore skill inside ApplicantSkillsVM.
I have a model which is list List<Applicant> and that contains another list List<ApplicantSkillsVM> and ApplicantSkillsVM has a property skill. I want to ignore this (skill) while mapping. Its simple.
How can I do this in latest the AutoMapper version with EF6?
Here a running sample:
internal class Program
{
#region Methods
private static void Main(string[] args)
{
// Configure the mappings
Mapper.Initialize(cfg =>
{
cfg.CreateMap<ApplicantSkillVM, ApplicantSkill>().ForMember(x => x.Skill, x => x.Ignore()).ReverseMap();
cfg.CreateMap<ApplicantVM, Applicant>().ReverseMap();
});
var config = new MapperConfiguration(cfg => cfg.CreateMissingTypeMaps = true);
var mapper = config.CreateMapper();
ApplicantVM ap = new ApplicantVM
{
Name = "its me",
ApplicantSkills = new List<ApplicantSkillVM>
{
new ApplicantSkillVM {SomeInt = 10, SomeString = "test", Skill = new Skill {SomeInt = 20}},
new ApplicantSkillVM {SomeInt = 10, SomeString = "test"}
}
};
List<ApplicantVM> applicantVms = new List<ApplicantVM> {ap};
// Map
List<Applicant> apcants = Mapper.Map<List<ApplicantVM>, List<Applicant>>(applicantVms);
}
#endregion
}
/// Your source classes
public class Applicant
{
#region Properties
public List<ApplicantSkill> ApplicantSkills { get; set; }
public string Name { get; set; }
#endregion
}
public class ApplicantSkill
{
#region Properties
public Skill Skill { get; set; }
public int SomeInt { get; set; }
public string SomeString { get; set; }
#endregion
}
// Your VM classes
public class ApplicantVM
{
#region Properties
public List<ApplicantSkillVM> ApplicantSkills { get; set; }
public string Description { get; set; }
public string Name { get; set; }
#endregion
}
public class ApplicantSkillVM
{
#region Properties
public Skill Skill { get; set; }
public int SomeInt { get; set; }
public string SomeString { get; set; }
#endregion
}
public class Skill
{
#region Properties
public int SomeInt { get; set; }
#endregion
}
}
Initially my model ApplicantSkillsVM didnt have reference Id for Skill which should be nullable
So my model had to look like
public class ApplicantSkillsVM{
public int Id {get;set;}
public int? skillId{get;set;} //updated property
public Skill skill{get;set;}
}
The problem resolved

Deserializing complex JSON using C#

public class Rootobject
{
public EnPickthall enpickthall { get; set; }
}
public class EnPickthall
{
public _1 _1 { get; set; }
public _2 _2 { get; set; }
public _3 _3 { get; set; }
public _4 _4 { get; set; }
/* This goes on*/
public _6236 _6236 { get; set;}
}
//For Each of the above properties a separate class has been defined:
public class _1
{
public int id { get; set; }
public int surah { get; set; }
public int ayah { get; set; }
public string verse { get; set; }
}
public class _2
{
public int id { get; set; }
public int surah { get; set; }
public int ayah { get; set; }
public string verse { get; set; }
}
/* So On for all the properties */
I got this via JSON2CSHARP!
My problem is if I employ so many properties retrieving all Verses based upon their "Surah" would be very difficult & Impractical
Here I have a book in EnPickthall class which has a separate Class for every verse. Every Verse here has it's own class.
I have been scavenging Stack Overflow for hours.Is there any way I could simplify this JSON Classes.
My Code to Creating the object model :
var serializer = new DataContractJsonSerializer(typeof(RootObject_Quran));
var result= App_Code.FileIOHelper.ReadFromDefaultFile("ms-appx:///Assets/en.pickthall.json");
var ms = new MemoryStream(Encoding.UTF8.GetBytes(result));
var data = (RootObject_Quran)serializer.ReadObject(ms);
My JSON File Link : http://globalquran.com/download/data/download.php?data_by=json&quran_by_id[]=en.pickthall
Just have a single class called Verse.
public class Verse {
public int SurahId { get; set; }
public int AyaId { get; set; }
public String Text { get; set; }
}
You don't really need a key for each verse, as the surah/aya combination is sufficient to uniquely identify a verse.
This allows for easy serialization/deserialization and also allows for easy gathering into the entire Quran again, by ordering on Surah and Aya. You could then simply use LINQ to reassemble the entire book, ordered as state above. Or it would be incredibly simple to gather passages from it also, based on a search criteria e.g. 27:18-20
Json is nested with property en.pickthall than all data wrapper again into property like id numbers so i made class and that class has Dictionary to handle data and numbers
[JsonProperty(PropertyName = "en.pickthall")]
public Dictionary picthall {get;set;}
public class VerseObject
{
[JsonProperty(PropertyName = "en.pickthall")]
public Dictionary<int, Data> picthall {get;set;}
}
public class Data
{
[JsonProperty(PropertyName = "id")]
public int id;
[JsonProperty(PropertyName = "surah")]
public int surah;
[JsonProperty(PropertyName = "ayah")]
public int ayah;
[JsonProperty(PropertyName = "verse")]
public string verse;
}
class Program
{
static void Main(string[] args)
{
List<Data> v = new List<Data>();
using (StreamReader rdr = new StreamReader(#"C:\Temp\en.pickthall.json"))
{
var str = rdr.ReadToEnd();
var jsn = JsonConvert.DeserializeObject<VerseObject>(str);
foreach(var item in jsn.picthall.Select(x=>x.Value))
{
v.Add(item);
}
Console.ReadLine();
}
}
}

Set element name same as RootElement attribute

[XmlRootAttribute("ls")]
public class Request<T>
{
[XmlAttribute("ver")]
public string Version { get; set; }
[XmlElement("hdr")]
public Header Header { get; set; }
[XmlElement(Type = typeof(class2), ElementName = "ChildClass")]
public T Data { get; set; }
}
[XmlRoot("ChildClass")]
public class class2
{
[XmlElement("login")]
public string Property1{ get; set; }
}
[XmlRoot("ChildClass3")]
public class class3
{
[XmlElement("User")]
public string Property1{ get; set; }
}
When Request<class2> is serialized , Element name is "Data". I want element Name to be "ChildClass". when Request<class3> is serialized , Element name should be "ChildClass3".
How can i do that
As far as I know the element name must be known at compile time and so you can't try and use the Data objects XmlRoot or class name or similar as these aren't known at compile time. You'll need to define every possible type that you could expect Data to be set to. As follows:
[XmlRoot("ls")]
public class Request
{
[XmlAttribute("ver")]
public string Version { get; set; }
[XmlElement("ChildClass2",typeof(class2))]
[XmlElement("ChildClass3",typeof(class3))]
public object Data { get; set; }
}
public class class2
{
[XmlElement("login")]
public string Property1 { get; set; }
}
public class class3
{
[XmlElement("User")]
public string Property1 { get; set; }
}
The following two objects:
var exampleObject = new Request
{
Version = "versionExample",
Data = new class2 { Property1 = "property1Example" }
};
var exampleObject2 = new Request
{
Version = "versionExample",
Data = new class3 { Property1 = "property1Example" }
};
Then serialized to:
<ls ver="versionExample">
<ChildClass2>
<login>property1Example</login>
</ChildClass2>
</ls>
<ls ver="versionExample">
<ChildClass3>
<User>property1Example</User>
</ChildClass3>
</ls>

Categories

Resources