Creating ViewModel that contains parent class properties in ASP.NET MVC - c#

I am trying to understand how to create a ViewModel that contains properties from a class in my domain model as well as properties from a parent class.
I want to have a ViewModel that contains all of the LoadSession properties and the TradingPartner Description, but I'm not sure how to map this all up in the ViewModel. Any help or advice would be greatly appreciated.
This is my main class I'm accessing named LoadSession:
public partial class LoadSession
{
public LoadSession()
{
this.AcceptedTransactions = new HashSet<AcceptedTransaction>();
this.RejectedTransactions = new HashSet<RejectedTransaction>();
}
public int LoadSessionId { get; set; }
public int Import { get; set; }
public string FilePath { get; set; }
public string TradingPartnerBatchId { get; set; }
public System.DateTime Started { get; set; }
public int RecordsOnFile { get; set; }
public int RecordsAfterGroupFilter { get; set; }
public int RecordsAccepted { get; set; }
public int RecordsRejected { get; set; }
public System.DateTime Completed { get; set; }
public bool Success { get; set; }
public Nullable<int> Extract { get; set; }
public virtual ICollection<AcceptedTransaction> AcceptedTransactions { get; set; }
public virtual Extract Extract1 { get; set; }
public virtual Import Import1 { get; set; }
public virtual ICollection<RejectedTransaction> RejectedTransactions { get; set; }
}
The Import property is a foreign key for this Import class (Import = ImportId):
public partial class Import
{
public Import()
{
this.GroupPlans = new HashSet<GroupPlan>();
this.ImportGroups = new HashSet<ImportGroup>();
this.MatchingGroups = new HashSet<MatchingGroup>();
this.LoadSessions = new HashSet<LoadSession>();
}
public int ImportId { get; set; }
public string Description { get; set; }
public int Format { get; set; }
public int Interface { get; set; }
public virtual Interface Interface1 { get; set; }
public virtual Format Format1 { get; set; }
public virtual ICollection<GroupPlan> GroupPlans { get; set; }
public virtual ICollection<ImportGroup> ImportGroups { get; set; }
public virtual ICollection<MatchingGroup> MatchingGroups { get; set; }
public virtual ICollection<LoadSession> LoadSessions { get; set; }
}
The Interface property is a foreign key for this Interface class (Interface = InterfaceId):
public partial class Interface
{
public Interface()
{
this.Extracts1 = new HashSet<Extracts1>();
this.Imports = new HashSet<Import>();
}
public int InterfaceId { get; set; }
public string Description { get; set; }
public int TradingPartner { get; set; }
public virtual ICollection<Extracts1> Extracts1 { get; set; }
public virtual ICollection<Import> Imports { get; set; }
public virtual TradingPartner TradingPartner1 { get; set; }
}
And the TradingPartner property is a foreign key for this TradingPartner class (TradingPartner = TradingPartnerId):
public partial class TradingPartner
{
public TradingPartner()
{
this.Interfaces = new HashSet<Interface>();
}
public int TradingPartnerId { get; set; }
public string Description { get; set; }
public virtual ICollection<Interface> Interfaces { get; set; }
}

Well, those are all your domain objects right...
Create a repository that takes your Domain object and transforms then to into a view model with the properties you need...
I am not sure what it is your view needs, but from your statements you state that you want properties of Load session + TradingPartner.Description So create something like this...
public class LoadSessionTradingPrtNrVM
{
public LoadSession()
{
this.AcceptedTransactions = new HashSet<AcceptedTransaction>();
this.RejectedTransactions = new HashSet<RejectedTransaction>();
}
public int LoadSessionId { get; set; }
public int Import { get; set; }
public string FilePath { get; set; }
public string TradingPartnerBatchId { get; set; }
public System.DateTime Started { get; set; }
public int RecordsOnFile { get; set; }
public int RecordsAfterGroupFilter { get; set; }
public int RecordsAccepted { get; set; }
public int RecordsRejected { get; set; }
public System.DateTime Completed { get; set; }
public bool Success { get; set; }
public Nullable<int> Extract { get; set; }
public string Description { get; set; }
public virtual ICollection<AcceptedTransaction> AcceptedTransactions { get; set; }
public virtual Extract Extract1 { get; set; }
public virtual Import Import1 { get; set; }
public virtual ICollection<RejectedTransaction> RejectedTransactions { get; set; }
}
To get from Domain models to ViewModels you would use a repository, or some other pattern that takes what you get from your database and transforms it into what you need for your views.
This is kind of raw, but the theory should hold...
public class DataRepository {
LoadSessionTradingPrtNrVM TransformToVM(LoadSession inputA, TradingPartner inputB){
LoadSessionTradingPrtNrVM newOBJ = new LoadSessioNTradingPrtNrVM();
newOBJ.LoadSessionId = ipnutA.LoadSessionID;
newOBJ.Import = inputA.Import
//Here is the property from your Transform object
newOBJ.Description = inputB.Description
//... Continue to transform one object into the other...
//You could add as many members from as many different objects as you want into
//Your view model following that pattern.
}
}
I didn't have a chance to run this through a C# compiler, but you should get the general idea. I am sure there is a more elegant pattern that can accomplish the same thing. But this is a decent solution off the top of my head.

Another option is to include the domain model objects as properties in the view model. For example:
// View model.
public class UserViewModel
{
public AddressModel Address; // Assuming "AddressModel" is a doman model.
public string FirstName;
public string LastName;
}
And in the view you can access the properties as:
#Model.Address.AddressLine1
#Model.Address.City
// etc...
The Html helpers handle this just fine, but if you are manually naming inputs in your view don't forget to adjust those names to match.

Related

AutoMapper: Converting a tree to an entity list

I have "Source" classes and "Destination" class:
public class ActionSource
{
public string Action { get; set; }
public IEnumerable<PlaceSource> Places { get; set; }
}
public class PlaceSource
{
public string Place { get; set; }
public IEnumerable<EventSource> Events { get; set; }
}
public class EventSource
{
public string Event { get; set; }
}
public class EventInfoDestination
{
public string Action { get; set; }
public string Place { get; set; }
public string Event { get; set; }
}
How can a map ActionSource data to IEnumerable<EventInfoDestination> with AutoMapper?
There isn't much auto about this mapping. You should do it by hand. AM would only get in the way.
from place in source.Places
from ev in place.Events
select new EventInfoDestination { Action = source.Action, Place = place.Place, Event = ev.Event};

ASP.NET Core Entity Framework Core inheritence

There is a model class called Review.
ReviewModel is used from StoreModel and Menu model.
In StoreModel.cs
[Table ("Stores")]
public class StoreModel
{
[Key]
public int Id { get; set; }
public string StoreName { get; set; }
public string StoreShortDescription { get; set; }
public string StoreFullDescription { get; set; }
public string StoreAddress { get; set; }
public ICollection<MenuModel> Menus { get; set; }
public ICollection<ReviewModel> Reviews { get; set; }
public StoreModel ()
{
Menus = new Collection<MenuModel> ();
Reviews = new Collection<ReviewModel> ();
}
}
in MenuModel.cs
[Table ("Menus")]
public class MenuModel
{
[Key]
public int Id { get; set; }
public string MenuName { get; set; }
public string MenuShortDescription { get; set; }
public string MenuThumbnailUrl { get; set; }
public int MenuPrice { get; set; }
public ICollection<ReviewModel> MenuReviews { get; set; }
public MenuModel ()
{
MenuReviews = new Collection<ReviewModel> ();
}
}
In this case, how should I implement this?
Create a base ReviewModel class and have 2 subclass (StoreReview, MenuModel)
or
Use ReviewModel for both StoreModel and MenuModel (how?)
or
thoughts?
If the ReviewModel properties are the same in both (StoreModel and MenuModel) there is nothing special to do, just use ReviewModel as it is being used in your shown code for both models.
In any case, just add an enum property to ReviewModel to know wether it is a StoreModelReview or a MenuModelReview.
Your ReviewModel might look like this: (creating many 2 many relationship)
[Table ("Reviews")]
public class ReviewModel
{
[Key]
public int Id { get; set; }
public ReviewEnum Type { get; set; }
public ICollection<MenuModel> Menus{ get; set; }
public ICollection<StoreModel> Stpres{ get; set; }
}

Nested Collection Mapping in Automapper

Am trying to map nested collections using automapper and I have done the basic setup and configuration. When I try to do the map it the nested values are coming as null. I have tried to follow few posts and put together something. I want the list to have a hierarchy instead of flattening. Any help around this would be great.
Source Entities:
public class OuterEntity
{
public int ID { get; set; }
public string Name { get; set; }
public List<InnerEntity> InnerEntityList { get; set; }
}
public class InnerEntity
{
public int InnerId { get; set; }
public string InnerName { get; set; }
public List<InnerMostEntity> InnerMostList { get; set; }
}
public class InnerMostEntity
{
public int InnerMostId { get; set; }
public string InnerMostName { get; set; }
public DateTime ModifiedDate { get; set; }
}
Destination Entities:
public class OuterEntityDTO
{
public int ID { get; set; }
public string Name { get; set; }
public List<InnerEntity> InnerEntityList { get; set; }
}
public class InnerEntityDTO
{
public int InnerId { get; set; }
public string InnerName { get; set; }
public List<InnerMostEntity> InnerMostList { get; set; }
}
public class InnerMostEntityDTO
{
public int InnerMostId { get; set; }
public string InnerMostName { get; set; }
public DateTime ModifiedDate { get; set; }
}
Controller Class:
public List<OuterEntityDTO> GetAll()
{
var outerEntityList = myRepo.GetAll(); //Type of List<OuterEntity>
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<OuterEntity, OuterEntityDTO>().ReverseMap();
cfg.CreateMap<InnerEntity, InnerEntityDTO>().ReverseMap();
cfg.CreateMap<InnerMostEntity, InnerMostEntityDTO>().ReveseMap();
});
config.AssertConfigurationIsValid();
var innerMostDTO = Mapper.Map<List<OuterEntity>,List<OuterEntityDTO>>(outerEntityList);
//The inner list at first level itself is null.
return innerMostDTO;
}
Am trying to achieve this in DOT NET Core. Autommaper version is 6.1.1
I think you should have a wrong class hierarchy in DTO classes, as you have
public List<InnerMostEntity> InnerMostList { get; set; }
in public class InnerEntityDTO, you should write it as
public List<InnerMostEntityDTO> InnerMostList { get; set; }

Custom Relationship in Entity Framework

I have got the following three tables (just an example)
public class User
{
public int id { get; set; }
public string name { get; set; }
public List<Code> Codes { get; set; }
}
public class Device
{
public int id { get; set; }
public string name { get; set; }
public List<Code> Codes { get; set; }
}
public class Code
{
public int id { get; set; }
public int entity_id { get; set; }
public string entity_type { get; set; }
public string code { get; set; }
}
Now a code can either belong to a User or a Device, which will be determined by the value of entity_type (i.e. 'user' or 'device'). How can this be achieved in Entity Framework ?
You could change your Code class to
public class Code
{
public int id { get; set; }
public User user { get; set; }
public Device device { get; set; }
public string code { get; set; }
}
This way one of those properties can be null.
Hope it helps.
The drawback is that you could have a code that have a user an a device

ASP MVC4 / Relation between classes on creation

Hello everybody and thanks for reading and tryin to help.
I'm a beginner in asp.
I Have two classes :
public class Organisation
{
public int OrganisationId { get; set; }
public string Nom_Organisation { get; set; }
public string Adresse_Organisation { get; set; }
public string Mail_Organisation { get; set; }
public DateTime Date_Ajout_Org { get; set; }
public virtual ICollection<Contrat> contract { get; set; }
public virtual ICollection<Ticket> Ticket_Org { get; set; }
public virtual ICollection<Interlocuteur> Interlocuteurs { get; set; }
public virtual ICollection<Environnement> Environments { get; set; }
public virtual ICollection<Outils> Outils { get; set; }
public virtual ICollection<Support> Supports { get; set; }
public Organisation()
{
}
}
and
public class Contrat
{
public int ContratId { get; set; }
public DateTime Date_Conclu { get; set; }
public string Reference { get; set; }
public string Commentaire { get; set; }
public virtual Organisation Orga{ get; set; }
[Required]
public int TypeContratId { get; set; }
public virtual TypeContrat Type { get; set; }
public Contrat()
{
}
}
I want to create an Organisation then add to it the contract. The thing is that i really don't see how. I create the Organisation with the generated controller but when i try to think about a way to create the Contract by sending to it the Organisation ID.
I want to add to the default generated table a button that send to the action that create the contract with the ID of the organisation selected.
Hope that u've understood my question! Thanks in advance.
I think that you use Entities Framework. If so, then you need not worry about it
just create Organisation and to add Contrat in ICollection<Contrat> contract
Organisation newOrg = new Organisation();
newOrg.contract = new List<Contrat>();
newOrg.contract.add(new contract())
context.Organisation.Add(newOrg);
context.save();
Or you can use Guid how other way:
change to:
public int OrganisationId { get; set; } => public Guid OrganisationId { get; set; }
Organisation newOrg = new Organisation();
newOrg.OrganisationId = Guid.New();
contract newContract = new contract();
newContract.OrganisationId = newOrg.OrganisationId;
context.Organisation.Add(newOrg);
context.save();

Categories

Resources