Implement Tag database - asp.net

Well hi everyone I'm kinda new on Asp.net Mvc, and need some help to improve, in my project that I'm working at, I need to register a user and in the register the user must choose some tags that are categories related to the subject of my website, the thing is that i have a database that looks like this
Tag
public int TagId{get;set;}
public string TagName{get;set;}
public string TagColor{get;set;}
TagUser
public int TagUserId{get;set;}
public int UserId{get;set;}
I read that EF constructs the tables when there is a many to many relationship, it construct the middle table automatically so in my case do i just need to have the first model and my user model? or should i use the 2 models above plus the user model, with the second approach i don't know how to relate de data i can define the TagUserId as primary key and UserId as foreignkey and relate the tables, but do i need this? or can i do that with the first approach if someone can give me a tip i appreciate a lot. :)
Ps: Sorry for my bad English

You can keep a Tags property of type IList<Tag> in your User class and a Users property in your Tag class of type IList<User>. Entity Framework will create a third table to store the many to many association between Tag and User.
public class Tag
{
public int Id {set;get;}
public string TagName {set;get;}
public virtual IList<User> Users { get; set; }
}
public class User
{
public int Id {set;get;}
public string UserName {set;get;}
public virtual IList<Tag> Tags { get; set; }
}

Related

How can I store multiple images in a database with a Blazor application?

I have an application that shows a form to the users. The form is taken by the server and stored in a database where the information can be read on another page in the application. Part of the form takes an image, where the image is converted to a Base64 string and sent to Azure to be stored, and the URL to the image is stored in the database as a string. This all works fine. My trouble comes from trying to implement a feature where users can select multiple images.
I tried changing the string Image {get;set;} to a List<string> {get;set;} where the database would just store a list of the URLs where I could iterate through them in the application. This obviously did not work, as through some research, I learned that databases cannot store lists.
I am now wondering what I can do here. Is there a simpler way of doing this that I'm missing? What am I doing wrong?
I tried changing the string Image {get;set;} to a List
{get;set;} where the database would just store a list of the URLs
where I could iterate through them in the application. This obviously
did not work, as through some research, I learned that databases
cannot store lists.
You can try to use the following methods:
Add separator between the Image urls. Use string Image {get;set;} to store the image urls, the value like this: "image1url,image2url,etc" (use the , as the separator). You can consider using the String.Join Method.
Create a new Image table to store the Image information (contains ID, Name, Urls), then configure one-to-many relationship between the Main table and the Image model. In the Main model, use navigation property to add the Image. Code like this:
public class Main
{
public int Id { get; set; }
public string Name { get; set; }
public List<Image> Images { get; set; }
}
public class Image
{
public int Id { get; set; }
public string Name { get; set; }
public string Url { get; set; }
}
More detail information about the Entity relationship, see:
Relationships
Configuring One To Many Relationships in Entity Framework Core
Saving Related Data

Pull external data into model in ASP.NET MVC

I am new to MVC. I went through the getting started guide for MVC 5 by Microsoft and have some really basic understanding of how things work. What I am looking to do is create a view page which display data from my domain model and related data that is not part of the domain model (the related data is on another sql server which I am not inserting or updating records. It's just related data I can associate with the data in my domain model).
For simplicity lets say I have a domain model that includes:
Student with Id Firstname, LastName, CourseId
Course with Id, Name, Department, ExtraInfoId
and I want to create another "model" (not sure if model is the correct term for this)
ExtraInfo with ExtraInfoId, Time, Location
The ExtraInfo is related to the Course by ExtraInfoId. ExtraInfo won't be in the database I am creating or updating. It is a external database that I want to connect to and pull data out of for display purpose, exampe get a student's Firstname, the course taken and then any "ExtraInfo" related to the Course.
I hope this makes sense. Any information or some quick sample code would be much appreciated.
Thanks!
Let's assume you have two class, one for your model
public class Student{
public string Name {get;set;}
public string LastName {get;set;}
public int CourseId {get;set;}
public string Name {get;set;}
public string Department {get;set;}
public ExtraInfo ExtraInfos {get;set}
}
public class ExtraInfo {
public int ExtraInfoId {get;set;}
public DateTime? Time {get;set;}
public string Location {get;set;}
}
Then in you controller you valorize first the Student class, then the ExtraInfos property of the student class and return the student class to you view, as a viewmodel.
var student = GetMyStudent(id); //method for accessing your student's data, could be linq with EF, or a httpclient call
student.ExtraInfos = GetExtraInfo(id); //same
return View(student);

.NET identity user, separation of conserns

I am trying to use .NET identity.
My user has properties which are related to auth. For example, email address, password, projects user has access to, etc.
Also, the user has other fields, for example favourite color.
Because color is not related to authentication, I don't want to add color as a property of ApplicationUser : IdentityUser {}.
But somehow I need to write values into that field, so I could write a repository, which takes the regular User object. But in that case I need to write the repository, hash the password myself, so what's the point having .NET Identity?
A third solution would be to make 2 tables, one for the ApplicationUser, and one for the related properties, but we already have a database, and I don't want to change everything.
One more idea what I could think of is to have ApplicationUser : IdentityUser {} as basibally a copy of User (I can't inherit from user and IdentityUser too, and can't chain it, because of database first) and have a separate AuthenticationUser : IdentityUser in the auth. context.
How sould I do it?
thanks
I think for this issue you have to change your model like:
public class Person
{
public string Color { get; set: }
public int RoleId { get; set: }
public Role Role { get; set: }
public ICollection<UserAuthentication> UserAuthentications { get; set: }
}
public class UserAuthentication
{
public Person Person { get; set: }
public int PersonId { get; set: }
}
With these models you don't have this problem.
If you have any data, you can displace that using TSql.

Displaying multiple lists of data in a view (i.e. CustomerContacts, CustomerLocations)

I have a CustomersController and in the Detail.cshtml view I need to display a list of that Customer's contacts and a list of that Customer's locations. I have a Detail(int? id) ActionResult and I have access to my CustomerService from within the controller. As of now in my Detail ActionResult I am able to do:
var cust = _custService.GetCustomerById(id);
return View(cust);
How would one recommend getting the rest of my lists in the view. I think I will create a GetContacts(customerID), GetLocations(CustomerID) within my CustomerService and then call them just like I call GetCustomerByID above. If I were to do it this way how would I have access to these lists in my view.
The next thing I was thinking about was possibly creating a ViewModel that has all of the basic customer properties like customer.Name, customer.Phone but then trying to figure out how I also make sure the ViewModel has the customer's contacts and locations. Would I just add 2 more properties to the ViewModel like customer.contacts and customer.locations since EF6 will make them available to me?
Any suggestions on the best way to go about getting multiple lists of information related to an entity in a view? Customer contacts and Customer locations are both one-to-many
The best practice is using a view model to transfer the data, as you have thought about.
public class CustomerDetailViewModel {
public string Name { get; set; }
public string Phone { get; set; }
public List<Contact> Contacts { get; set; }
public List<Location> Locations { get; set; }
}

Slim version of Large Object/Class

I have a product class which contains 11 public fields.
ProductId
ShortTitle
LongTitle
Description
Price
Length
Width
Depth
Material
Img
Colors
Pattern
The number of fields may grow with attributes for more specific product tyes. The description may contain a large amount of data.
I want to create a slim version of this product class that only contains the data needed. I'm only displaying 4 of the 12 fields when listing products on a category page. It seems like a waste to retrieve all of the data when most of it isn't being used.
I created a parent class of ProductListing that contains the 4 fields I need for the category page
ProductId
ShortTitle
Price
Img
Then created a class of Product that inherits from ProductListing containing all product data. It seems backwards as "ProductListing" is not a kind of "Product" but I just started reading about inheritance a few months ago so it's stil a little new to me.
Is there a better way to get a slim object so I'm not pulling data I don't need?
Is the solution I have in place fine how it is?
I personally do not favor inheritance for these kinds of problems because it can become confusing over time. Specifically, I try to avoid having two concrete classes in my inheritance hierarchy where one inherits from the other and both can be instantiated and used.
How about creating a ProductCoreDetail class that has the essential fields you need and aggregating it inside of the Product class. You can still expose the public fields by declaring them as public fields and proxying them to the nested ProductCoreDetail instance.
The benefit of this model is that any shared implementation code can be placed in ProductCoreDetail. Also, you can choose to define an additional interface IProductCoreDetail that both Product and ProductCoreDetail implement so that you can pass either instance to methods that just care about code information. I would also never exposed the aggregate instance publicly to consumer of Product.
Here's a code example:
// interface that allows functional polymorphism
public interface IProductCoreDetail
{
public int ProductId { get; set; }
public string ShortTitle { get; set; }
public decimal Price { get; set; }
public string Img { get; set; }
}
// class used for lightweight operations
public class ProductCoreDetail : IProductCoreDetail
{
// these would be implemented here..
public int ProductId { get; set; }
public string ShortTitle { get; set; }
public decimal Price { get; set; }
public string Img { get; set; }
// any additional methods needed...
}
public class Product : IProductCoreDetail
{
private readonly ProductCoreDetail m_CoreDetail;
public int ProductId { get { return m_CoreDetail.ProductId; } }
public string ShortTitle { get { return m_CoreDetail.ShortTitle; } }
public decimal Price { get { return m_CoreDetail.Price; } }
public string Img { get { return m_CoreDetail.Img; } }
// other fields...
public string LongTitle
public string Description
public int Length
public int Width
public int Depth
public int Material
public int Colors
public int Pattern
}
I agree with LBushkin that inheritence is the wrong approach here. Inheritence suggests that TypeB is a TypeA. In your case, the relationship is not quite the same. I used to create classes that were subsets of a large entity for things like search results, list box items, etc. But now with C# 3.5's anonymous type support and LINQ projections, I rarely need to do that anymore.
// C#
var results = from p in products
select new {
p.ProductId,
p.ShortTitle,
p.Price,
p.Img };
// VB.NET
Dim results = From p in products _
Select p.ProductId, p.ShortTitle, p.Price, p.Img
This creates an unnamed type "on-the-fly" that contains only the fields you specified. It is immutable so the fields cannot be changed via this "mini" class but it supports equality and comparison.
But when I do need to create a named type, I typically just create a separate class that has no relationship to the main class other than a lazy-loaded reference to the "full" version of the object.
I wouldn't use a separate class or inheritance.
For your slim version, why not just retrieve only the data you need, and leave the other fields empty? You might have two queries: one that fills all the fields, and another that only fills the slim fields. If you need to differentiate between the two, that's easy if one of the non-slim fields is NOT NULL in your DB; just check for null in the object.

Resources