Confused about DTOs when reading and editing. How to desing DTO for filling the form in VUEjs app? - api

I am trying to develop an enterprise-level application. I have domain and application services. I have created my DTOs for multiple purposes separately. But confused about which way I should use them from the API viewpoint.
I have complex objects lets say,
public class Entity{
public int Id { get; set; }
public string Name { get; set; }
public int? ManufacturerId { get; set; }
public virtual Manufacturer Manufacturer { get; set; }
}
public class Manufacturer{
public int Id { get; set; }
public string Text { get; set; }
}
And I have corresponding DTOs designed with composition now. It was separated before.
public class EntityBaseDto{
public string Name { get; set; }
}
public class EntityReadDto : EntityBaseDto{
public string Manufacturer { get; set; }
}
public class EntityWriteDto : EntityBaseDto{
public int? ManufacturerId { get; set; }
}
Now the question is,
I have a table which is filled with List<EntityReadDto> which is clear. Before, EntityReadDto also had the ManufacturerDto as fully included with id and text. Whenever I require to edit one of the entries from the table I was able to load the dropdown selected items or list of tags etc with the ids attached to the Manufacturer objects within ReadDtos. Now it is not possible. Since I wanted to simplify the codes I just converted them to strings that are read-only. Now I have created another endpoint to get an editable version of the record when needed. Ex: EntityWriteDto will be used to fill the form when the edit is clicked on a specific item. The manipulation will be carried on that DTO and sent with the PUT type request to edit the record.
I am not sure if this approach is ok for these cases. What is the best practice for this? I have many objects related to the entities from other tables. Is it ok to make a call to get an editable version from the backend or need to have it right away in a VUEjs app?

Related

What's the best way to go about implementing hashtag functionality in EF Core/Razor Pages?

I'm trying to implement hasthags into an application. I've configured the database already and even have a layout for how I'd like the form to look, however I'm not sure if it's possible to do what I want to do with Razor pages. I have the below classes:
public class Person
{
public int PersonId { get; set; }
public string FirstName { get; set; }
public string LastName{ get; set; }
public IList<PersonTag> PersonTags { get; set; }
}
public class Tag
{
public int TagId { get; set; }
public string TagName { get; set; }
public IList<PersonTag> PersonTags { get; set; }
}
public class PersonTag
{
public int PersonTagId { get; set; }
public int PersonId { get; set; }
public Person Person { get; set; }
public int TagId { get; set; }
public Tag Tag { get; set; }
}
And would like the form to look like this, where you see this input while editing a Person. You'd add a new hashtag by typing in the input box--hitting enter there (or pressing a button--not pictured) would create the tag in the Tag table and also create a new PersonTag relationship with the Person being edited, which would be saved on form submission. I guess the Tag could also get created on form submission if that's simpler. Clicking the "x" on one of the tags should also remove the PersonTag relationship
Is this something that's possible with razor pages? To this point I've only ever done simpler inputs (either single values or select lists), but in this case I need the user to have the option to enter free text multiple times. What kind of input would I need for these? Or would I need to do entirely special handling to pull the data on form submit, and just populate the tags with Javascript when the user adds them?

Reference another class using an index vs storing entire instance

In a class which needs to "contain information" about another class (sorry I don't know the terms for this), should I store the reference to that other class as something like an integer/id, or should I store it as an instance of the other class? What is this called, if there is a name for it?
As a very basic example, an app where we want to store what a user's favorite restaurant is:
public class User {
public int id { get; set; }
public string name { get; set; }
// id of restaurant...
// public int favoriteRestaurantId { get; set; }
// ...or entire instance of Restaurant type
// public Restaurant favoriteRestaurant { get; set; }
}
public class Restaurant {
public int id { get; set; }
public string name { get; set; }
}
Note: if you think this is off topic, please explain why this question would be allowed and is a highly rated/useful question, but mine is not: Interface vs Base class Or at the very least tell me what this is "called" so I can research it more myself. As far as I can tell from Stackoverflow's FAQ this question is on topic.
Your first variant
public int favoriteRestaurantId { get; set; }
only makes sense if you are only interested in the id and not the other attributes (name) of the restaurant object. Otherwise you will need some external container that stores all restaurant objects and have to search the container for the restaurant with the given id.
In your second variant
public Restaurant favoriteRestaurant { get; set; }
if you write
someUser.favouriteRestaurant = someRestaurant;
this also stores a reference to an existing someRestaurant. It will not copy the whole object. at least not in languages like C# and Java.
Only if you do something like
someUser.favouriteRestaurant = new Restaurant(someRestaurant);
the user will have its own copy of the restaurant object.
There are cases where this would make sense but in your example it is probably not a good idea for two reasons:
If for example the name of the someRestaurant changes, this should also change the name of favouriteRestaurant. This will not happen automatically if favouriteRestaurant is a copy.
It is a waste of memory.

How to access many to many object in .NET MVC via Razor

Using EF 7 I have an object that references a many to many table, using code first method.
public class EventUser
{
public string UserId { get; set; }
public User User { get; set; }
public int EventId { get; set; }
public Event Event { get; set; }
public string AdditionalInfo { get; set; }
}
I can pull a list of these when knowing EventId and display them in Razor. I want to link to each one of these objects back to the controller so a user could edit the AdditionalInfo field. Since the object doesn't have just one Id field, how can I send the appropriate data to the controller to access this object, since just using one Id will not be enough.
At this point, I can achieve this using:
<a asp-action="EditEventUser" asp-route-EventId="EventUser.EventId" asp-route-UserId="EventUser.UserId">Edit Event User</a>
But, I would like to know if I am ignorant about some other way this can be achieved in a cleaner way (if there is such a way).

ASP.NET MVC 4 database scaffolding self referential model

I have a constructed a model using code first in C#. The model literally represents a container element for a website building application, in other words, the model defines a Div tag or some such HTML element. Like a Div tag which can contain multiple child elements, I have tried to represent this in my model, but the scaffolding to the DB, does not give me what I'd expect.
I should get a new many to many joins table, but instead I only get a single column in the DB which expects a single int data type.
Here is the model:
public class ElementContainer
{
public int ElementContainerID { get; set; }
public int PageId { get; set; }
public int? ParentElementContainerID { get; set; }
public string ElementContainerName { get; set; }
public ElementType ElementType { get; set; }
public string ElementClass { get; set; }
public PageAsset PageAsset { get; set; } // content of container
public List<ElementContainer> NestedContainers { get; set; }
}
The last line is the self-referential attribute which just appears as a column called ElementContainer_ElementContainerID
Thanks in advance!
I agree with Bahman, DB first is easier.
While I haven't tried to do what you are trying, your code looks like a self-Join that would do exactly what you describe.
This is a One-to-Many relationship. EF Navigation will pull a List of all nested children containers.
If you want to create a many-to-many relationship with EF Code-First, you should create another Entity
public class ContainerChildren
{
public int ElementContainerID { get; set; }
public List<ElementContainer> NestedContainers { get; set; }
}
this reference should help you to get the exact idea http://blogs.msdn.com/b/wriju/archive/2011/05/14/code-first-ef-4-1-building-many-to-many-relationship.aspx

MVC4 / EF5 / Auto Increment

I'm not sure how to exactly word my question which is probably why I cannot find an example of this anywhere. I'm playing around with MVC4 & EF5 (Web API too) but I'm not sure how to proceed with the Model as I've never really had to do much with them before. I'm doing something around the Periodic Tablet of Elements and I want to make it so that I have a list built for an element with it's electron configuration. However, I'd like to have it just auto number based on the input order. How can I tell EF to auto-increment a field? Basically like a primary key field without that limitation behind it. Here's what I have so far - I'm just not sure how to proceed:
public class Elements
{
public int ElementID { get; set; }
public string Name { get; set; }
public int AtomicNumber { get; set; }
public string Symbol { get; set; }
public virtual Categories Category { get; set; }
public virtual States State { get; set; }
public virtual Occurences Occurence { get; set; }
public virtual ICollection<Configurations> Configuration { get; set; }
}
public class Categories
{
public int CategoryID { get; set; }
public string CategoryName { get; set; }
}
public class States
{
public int StateID { get; set; }
public string StateName { get; set; }
}
public class Occurences
{
public int OccurenceID { get; set; }
public string OccurenceName { get; set; }
}
public class Configurations
{
public int ConfigurationID { get; set; }
public int Order { get; set; }
public int Value { get; set; }
}
Looking above what I'd like is for anytime a value is added to Configurations.Order the value starts at 1 and increases with each new 'row' but only for that specific ElementID.
Does that make sense? I was looking at using Data Annotations but I couldn't find anything that matched other than a Key Field but that'd make each Order a unique number - which I don't want. I feel like I'm not expressing this correctly because of all the stuff I've been looking at to figure it out, so here's a picture! yay!
This very well could be something that is better off from a programmatic standpoint. Even though this data changes once in a blue moon, I wanted to try and do it through EF if possible just so I know how.
Thanks a ton in advance. Also, if you see any other glaring errors, by all means let me know :) I rarely get to work with this side of web dev so I'm sure there's ways to do things better.
How can I tell EF to auto-increment a field?
You can't. Not even for a simple auto-incrementing primary key. Let alone for a field that should increment in relation to other values.
The HasDatabaseGeneratedOption mapping method is not a way to tell EF how to generate key values. It tells EF if and how the database generates values for properties, so EF knows how to respond to that.
So you either have to generate the order numbers in code, or let the database do it (by a trigger, or by mapping CUD actions on Configurations to stored procedures) and tell EF that the database computes the values by HasDatabaseGeneratedOption(DatabaseGeneratedOption.Computed) in the configuration of the Order property.