How to create instance of nested class? [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 2 years ago.
I have a viewmodel and it contains two viewmodel in ReaderBorrowViewModel, I'm not sure it's best practice but it makes sense to me. In GetReaderDetailModel method i got borrows from db. After every borrowed book i tried to get data for ReaderDetailViewModel which contains BookStateModel and BookViewModel.Getting all borrowed books i added to list in ReaderBorrowModel to send it client.I got Object reference not set to an instance of an object while i creating an instance of ReaderBorrowModel. What's my fault ?
public class BookStateViewModel
{
public int BookStateKey { get; set; }
public string Name { get; set; }
}
public class BookViewModel
{
public int BookKey { get; set; }
public string ISBN { get; set; }
public string Name { get; set; }
public string Author { get; set; }
}
public class ReaderBorrowModel
{
public int BorrowKey { get; set; }
public BookViewModel Book { get; set; }
public BookStateViewModel BookState { get; set; }
}
public class ReaderDetailViewModel
{
public MemberViewModel Member { get; set; }
public List<ReaderBorrowModel> Borrows { get; set; }
}
public async Task<ReaderDetailViewModel> GetReaderDetailModel(int memberKey)
{
ReaderDetailViewModel result = new ReaderDetailViewModel();
var borrows= borrowService.SelectIncludeMany(x => x.Member,k=>k.Book, d=>d.BookState).Where(x=>x.MemberKey== memberKey);
var member= borrows.Select(x => x.Member);
try
{
borrows.ToList().ForEach(o =>
{
var borrow = new ReaderBorrowModel
{
BorrowKey = o.BorrowKey,
Book = new BookViewModel
{
BookKey = o.Book.BookKey ,
Name = o.Book.Name ,
ISBN = o.Book.ISBN ,
Author = o.Book.Author.Name
},
BookState = new BookStateViewModel
{
BookState Key = o.BookState Key,
Name= o.BookState.Name
}
};
result.Borrows.Add(odunc);
});
}
catch (Exception ex)
{
throw ex;
}
return result;
}

You have not initialized the property to a new list. Try the below snippet. Once the list is set to a new list, you don't get null reference exception
public class ReaderDetailViewModel
{
public ReaderDetailViewModel() {
Borrows = new List<ReaderBorrowModel>();
}
public MemberViewModel Member { get; set; }
public List<ReaderBorrowModel> Borrows { get; set; }
}
Note
As a good practice, you can always initialize the list / dictionary etc to a new list or new dictionary etc so that you don't run into null reference exceptions.

Related

How to manually map a List of object to a list of DTO?

I have these:
public class FamilyHead
{
public Guid HeadId { get; set; }
public string Name { get; set; }
}
public class Citizen
{
public Guid Id { get; set; }
public string Name { get; set; }
public short Age { get; set; }
// more properties
[ForeignKey("FamilyHead")]
public Guid HeadId { get; set; }
public virtual FamilyHead FamilyHead { get; set; }
}
public class CitizenDTO
{
public Guid Id { get; set; }
public string Name { get; set; }
public short Age { get; set; }
public Guid HeadId
public string HeadName { get; set; }
}
I can manually map it via extension method if it is a single instance:
public static CitizenDTO ToDTO(this Citizen citizen)
{
if (citizen == null) return null;
return new CitizenDTO {
Id = citizen.Id,
Name = citizen.Name,
HeadId = citizen.HeadId,
HeadName = citizen.FamilyHead.Name
}
}
var dto = aCitizen.ToDTO();
But how to map a list of citizens? I think Select() might do the work but I only know how to do it if the model and the dto have a same structure. Like this example:
IEnumerable<int> integers = new List<int>() { 1, 2, 3, 4, 5 };
IEnumerable<string> strings = integers.Select(i => i.ToString());
So how to map a list of it?
You can use Linq Select() as you used for string in your question, no need to write long extension method
IEnumerable<CitizenDTO> dto = citizens.Select(x => x.ToDTO());
I found the answer before finishing my question. Just iterate through the list and add mapped DTO to it. Silly me
// Extension method
public static IEnumerable<CitizenDTO> ToDTO(this IEnumerable<Citizen> citizens)
{
if (citizen == null) return null;
var dto = new List<CitizenDTO>();
foreach(var citizen in citizens) {
dto.Add(citizen.ToDTO());
}
return dto;
}
// How to use
IEnumerable<CitizenDTO> result = listOfCitizens.ToDTO();

How to check the value passed into the dictionary [duplicate]

This question already has answers here:
The model item passed into the dictionary is of type .. but this dictionary requires a model item of type
(7 answers)
Closed 3 years ago.
The details are being fetched in the controller correctly but value passed in the view is incorrect. Therefore I am getting the following error:
The model item passed into the dictionary is of type 'System.Int64', but this >dictionary requires a model item of type >'estatebranch.ViewModels.RentRegisterViewModel'
My controller has following action method
public ActionResult RentRegister(int propertyId)
{
try
{
using (estatebranchEntities db = new estatebranchEntities())
{
RentRegisterViewModel objRentRegister = new RentRegisterViewModel();
objRentRegister.balance = db.PropertyDetails.Where(m => m.propertyid == propertyId).Select(m => m.balance).SingleOrDefault();
return View(objRentRegister.balance);
}
}
catch (Exception)
{
throw;
}
}
My View model is as follow:
public class RentRegisterViewModel
{
public int recordid { get; set; }
public int propertyid { get; set; }
public int month { get; set; }
public int year { get; set; }
public long amountpaid { get; set; }
public System.DateTime paymentdate { get; set; }
public long interest { get; set; }
public Nullable<long> balance { get; set; }
public virtual PropertyDetail PropertyDetail { get; set; }
}
try changing this line:
return View(objRentRegister);

C# clone static class [duplicate]

This question already has answers here:
How do I clone a generic list in C#?
(29 answers)
Closed 4 years ago.
I have studied deep copies over the day but I still don't quite get it.
Here's what I want.
static class MyList
List<MenuData> Menu1 = MenuList.Menus.ToList();
List<MenuData> Menu2 = MenuList.Menus.ToList();
I use Menu2 on remove method.
However, Menu1 was also deleted.
I realize that Menu1 and Menu2 were deleted together because of Swallow Copy.
They also referred to samples of other people, but failed.
static class MenuList
{
public class MenuData
{
public string ID { get; set; }
public string Text { get; set; }
public string Image { get; set; }
public Boolean Expanded { get; set; }
}
public static List<MenuData> Menus = new List<MenuData>()
{
new MenuData {
ID = "1",
Text = "Service",
Image = "file_path.png",
Expanded = false
},
};
public static T Clone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T)formatter.Deserialize(ms);
}
}
public static List<MenuData> CopyMenus = MenuList.Clone(MenuList.Menus);
}
ErrMessage : The format 'Models.MenuData' is not marked serializable.
It was asked to reduce further waste of time.
I don't know why did you want to clone a static class
but if you want to Serialize object you need to use a attribute Serializable to tag your Serialize Class.
[Serializable]
public class MenuData
{
public string ID { get; set; }
public string Text { get; set; }
public string Image { get; set; }
public Boolean Expanded { get; set; }
}
serialization
EDIT
If you want to clone object, your clone class can implement ICloneable interface.
Here is a sample.
public class MenuList
{
public List<MenuData> Menus { get; private set; }
public MenuList()
{
Menus = new List<MenuData>()
{
new MenuData {
ID = "1",
Text = "Service",
Image = "file_path.png",
Expanded = false
},
};
}
public class MenuData : ICloneable
{
public string ID { get; set; }
public string Text { get; set; }
public string Image { get; set; }
public Boolean Expanded { get; set; }
public object Clone()
{
return new MenuData()
{
ID = this.ID,
Text = this.Text,
Expanded = this.Expanded,
Image = this.Image
};
}
}
public List<MenuData> CloneMenus()
{
return Menus.Select(o => (MenuData)o.Clone()).ToList();
}
}
You can get Clone List on outside.
MenuList list = new MenuList();
List<MenuData> CloneList = list.CloneMenus();

already defines member called X c# model

Have class Books and there i should implement two foreign tables. Comments and Rating. This is the class:
public class Books
{
public Books()
{
CommentsList = new List<Comments>();
}
public Books()
{
RatingList = new List<Rating>();
}
public virtual int Id { get; set; }
public virtual string Title { get; set; }
public virtual string Category { get; set; }
public virtual string ISBN { get; set; }
public virtual string Description { get; set; }
public virtual string Image { get; set; }
// public virtual int CategoryId { get; set; }
public virtual Categories Categories { get; set; }
public virtual IList<Comments> CommentsList { get; set; }
public virtual IList<Rating> RatingList { get; set; }
public virtual void AddComment(Comments comm)
{
comm.Books = this;
CommentsList.Add(comm);
}
public virtual void AddRating(Rating rating)
{
rating.Books = this;
RatingList.Add(rating);
}
}
It gives an error
Error 2 already defines a member called 'Books' with the same
parameter types
How to solve this to have possibility to add comments and rating to a book ?
You have the same constructor two times. I guess you're using Entity Framework and if I recall correctly, you want to change those ILists to ICollections to use the Entity Framework lazy-loading features.
Change
public class Books
{
public Books()
{
CommentsList = new List<Comments>();
}
public Books()
{
RatingList = new List<Rating>();
}
}
To :
public class Books
{
public Books()
{
CommentsList = new List<Comments>();
RatingList = new List<Rating>();
}
}
You simply can't have two constructors that have the same signature. You should consider using a builder pattern instead.
You would typically hide the constructors (make them private) and instead expose static methods like CreateFromComments and CreateFromRatings.
private Books() { }
public static Books CreateFromComments()
{
var ret = new Books();
ret.CommentsList = new List<Comments>();
return ret;
}
public static Books CreateFromRatings()
{
var ret = new Books();
ret.RatingsList = new List<Ratings>();
return ret;
}
may be you can pass a boolean param to set the list to initialize...
public Books(bool comments)
{
if (comments)
CommentsList = new List<Comments>();
else
RatingList = new List<Rating>();
}

AutoMapper - Map a complex object using naming conventions without providing inner mappings

I have two complex objects that have exactly the same properties.
Now with AutoMapper, I usually will need to do something like this:
Mapper.CreateMap<ObjA, ObjB>();
But if one of the objects has a complex inner object, Ill need to map it too:
Mapper.CreateMap<ObjAInner, ObjBInner>();
Now I have a large object that expands all the time.
I don't want to maintain the CreateMap calls each time I add a complex inner object to the main object.
Now I can probably solve this with a recursive reflection on the main object and map all the types but I'd prefer not to do that.
Is there anyway I can tell AutoMapper to Create a full recursive map(also for inner types) on a complex object?
Something like this:
Mapper.CreateFullMapOnIdenticalObjectsWithInnerTypes<ObjA, ObjB>();
Edit:
Here's an example:
two identical classes with a different namespace:
namespace NameSpace1
{
public class Obj1
{
public string Str { get; set; }
public int Num { get; set; }
public InnerObj1 InnerObj1 { get; set; }
}
public class InnerObj1
{
public string StrInner1 { get; set; }
public int NumInner1 { get; set; }
public AnotherInnerObj1 AnotherInnerObj1 { get; set; }
}
public class AnotherInnerObj1
{
public string Str { get; set; }
}
}
namespace NameSpace2
{
public class Obj1
{
public string Str { get; set; }
public int Num { get; set; }
public InnerObj1 InnerObj1 { get; set; }
}
public class InnerObj1
{
public string StrInner1 { get; set; }
public int NumInner1 { get; set; }
public AnotherInnerObj1 AnotherInnerObj1 { get; set; }
}
public class AnotherInnerObj1
{
public string Str { get; set; }
}
}
Create a mock NameSpace1.Obj1:
public static NameSpace1.Obj1 Create()
{
return new NameSpace1.Obj1
{
Num = 10,
Str = "Obj1",
InnerObj1 = new NameSpace1.InnerObj1
{
NumInner1 = 11,
StrInner1 = "InnerObj1",
AnotherInnerObj1 = new NameSpace1.AnotherInnerObj1
{
Str = "AnotherInnerObj1"
}
}
};
}
This is what I would like:
Mapper.CreateMap<NameSpace1.Obj1, NameSpace2.Obj1>();
var obj1 = Create();
var obj2 = Mapper.Map<NameSpace2.Obj1>(obj1);
But this will throw an exception since I need to define inner mappings. This will work:
Mapper.CreateMap<NameSpace1.Obj1, NameSpace2.Obj1>();
Mapper.CreateMap<NameSpace1.InnerObj1, NameSpace2.InnerObj1>();
Mapper.CreateMap<NameSpace1.AnotherInnerObj1, NameSpace2.AnotherInnerObj1>();
var obj1 = Create();
var obj2 = Mapper.Map<NameSpace2.Obj1>(obj1);

Categories