I am an absolute novice at using ASP.NET MVC3, and I'm having a great deal of trouble figuring out how to do something that is probably very easy.
Here's my public class:
public class Proposal
{
ProposalDBEntities proposalDB =
new ProposalDBEntities();
public int ID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public DateTime Target_Finish_Date { get; set; }
public decimal Estimated_Cost { get; set; }
public int Staffing { get; set; }
public decimal Maintenance { get; set; }
public DateTime Date_Added { get; set; }
public int Rating { get; set; }
public decimal VoteAverage { get; set; }
}
I simply want an individual logged-in user to be able to set the value for public int Rating. That is, if the user sets it to 37, he'll see the value 37 when he logs in. But another user who sets it to 50 will see 50. In other words, the value for Rating will be different depending on who's logged in. This seems like it wouldn't be hard at all, but I have no idea where to begin. Any help would be greatly appreciated.
To display the rating: In your view, you would have something like #Html.DisplayFor(p => p.Rating). This is RAZOR syntax. If you are using ASPX, it would be <%: #Html.DisplayFor(p => p.Rating) %>
To have users able to edit the rating (in Entity Framework): How will your user input the rating? Personally, as a beginner, you can create an Entity Data Model and generate code based on your database structure. Then, you can create a controller with CRUD (create, read, update, delete) principles that gives the user the ability to edit his/her rating (Keep in mind that there are views created in addition to edit: create, delete, details, and index. Use what is relevant to you.)
Lots of info to digest, I'm sure. Feel free to ask me anything. I'm in your shoes as well. Hope this helps.
Related
I am using Web API 2 with Breeze and Entity Framework 6. I have the following models.
public class ScoreCard: EntityBase
{
public string Title { get; set; }
public virtual List<ScoreCardSection> Sections { get; set; }
public String UserId { get; set; }
}
public class ScoreCardSection:EntityBase
{
public string Title { get; set; }
public int Index { get; set; }
public long ScoreCardId { get; set; }
public virtual List<ScoreCardQuestion> Questions { get; set; }
}
I want to fetch a score card with a list of sections. I execute a EntityQuery with an expand and it executes this URL:
/api/ScoreCards?$filter=Id%20eq%201L&$expand=Sections
I get back the following results:
[{"Title":"Catalyst Service Report","Sections":
[{"Title":"Worship","Index":0,"ScoreCardId":1,"Questions":null,"Id":1},
{"Title":"Message","Index":0,"ScoreCardId":1,"Questions":null,"Id":2},
{"Title":"Leader","Index":0,"ScoreCardId":1,"Questions":null,"Id":3},
{"Title":"Attendance","Index":0,"ScoreCardId":1,"Questions":null,"Id":4},
{"Title":"Security","Index":0,"ScoreCardId":1,"Questions":null,"Id":5}],
"UserId":"b9bd5256-dd18-4c1e-9907-dac9e7e4c01b","Id":1}]
So far, so good. Now we get to the problem. When I inspect the results during the success callback the sections property of the object is a empty array, even though the sections were sent back in the response.
What am I missing here? Thanks in advanced.
Ok, the solution to this problem seemed to be a few hours sleep.
For anyone who has this same issue the first part of the problem was that I didn't have a navigation property for ScoreCard on ScoreCardSection. Once I added that I got a "Self Referencing Loop" error. This was corrected by adding the BreezeControllerAttribute to my controller class.
Hope this is helpful to someone.
I wonder if I could get some help with the following. I'm retrieving set of data as follows using EF.
var booking = this.GetDbSet<Booking>().Include(c => c.BookingProducts.Select(d => d.Product.PrinterProducts.Select(e => e.ProductPrices))).Single(c => c.BookingId == bookingId)
Within a PrinterProduct there is a foreign key PrinterId for an additional entity Printer. With the Booking Entity I also have PrinterId also linked by foreign key to the additonal entity Printer.
What I'm hoping to do is retrieve only the PrinterProduct relating to the PrinterId held in the booking entity rather that all the PrinterProducts as in my code. I've tried to use Join but have tied myself in knots!
Grateful for any help!
Edit:
Object structure:
public class Booking
{
public Guid BookingId { get; set; }
public string BookingName { get; set; }
public Printer Printer { get; set; }
public IEnumerable<BookingProduct> BookingProducts { get; set; }
}
public class BookingProduct
{
public int BookingProductId { get; set; }
public Booking Booking { get; set; }
public Product Product { get; set; }
}
public class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public IEnumerable<PrinterProduct> PrinterProducts { get; set; }
}
public class PrinterProduct
{
public int PrinterProductId { get; set; }
public Product Product { get; set; }
public Printer Printer { get; set; }
public IEnumerable<ProductPrice> ProductPrices { get; set; }
}
public class ProductPrice
{
public int ProductPriceId { get; set; }
public PrinterProduct PrinterProduct { get; set; }
public decimal Price { get; set; }
}
public class Printer
{
public int PrinterId { get; set; }
public string PrinterName { get; set; }
public IEnumerable<Booking> Bookings { get; set; }
public IEnumerable<PrinterProduct> PrinterProducts { get; set; }
}
Given the newly added class structures in your question, I hope I can clear it up now.
From what I see, Bookings and Products have a many-to-many relation (where BookingProduct is used as the connection). The same is true for Product and Printer (where PrinterProduct is used as the connection).
From what I understand, you are trying to get from a singular Booking item to a singular PrinterProduct. I don't see any efficient way to do this without introducing the possibility of inconsistency with your data. You're expecting some Lists to return you one result. If it's only one result, why is it a List in the first place?
You have a single Booking. You take its BookingProducts. Now you have many items.
You take the Product from each individual BookingProduct. If all BookingProducts have the same product, you're in luck and will only have a List<Product> with a single Product in it. However, there is nothing stopping the system from return many different products, so we are to assume that you now hold a List of several Products
From each Product in the list, you now take all of its PrinterProducts. You now hold many PrinterProducts of many Products.
As you see, you end up with a whole list of items, not just the singular entity you're expecting.
Bookings, Products and Printers are all connected to eachother individually, like a triangle. I have seen scenarios where that is correct, but nine times out of ten, this is not what you want; and only leads to possible data inconsistency.
Look at it this way: Is it ever possible for the Product to have a Printer other than the Printer that is already related to the Booking? If not, then why would you have two relations? This only introduces the possibility that Booking.Printer is not the same as PrinterProduct.Printer.
Your relational model is set up to yield many results, but I think you expect a single result in some places. I would suggest taking another look at your data model because it does not reflect the types of operation you wish to perform on it. Change the many-to-many relations to one-to-many where applicable, and you should be able to traverse your data model in a more logical fashion, akin to the answer I provided in my previous answer.
If you've set up navigational properties, you can just browse to it:
var myBooking = ... //A single Booking, don't know how you retrieve it in your case.
var myPrinter = myBooking.Printer; //the Printer that is related to the Booking.
var myPrintproducts = myPrinter.PrintProducts; //The products that are related to the printer.
You don't need to keep nesting select statements, that only creates unnecessary confusion and overhead cost.
Keep in mind that you need to do this while in scope of the db context. Every time you try to access a property, EF will fill in the needed variables from the database. As long as there is an open db connection, it works.
Edit
If you really need to optimize this, you can use a Select statement. But you only need a single one. For example:
var myPrintproducts = db.Bookings.Single( x => x.ID == some_id_variable ).Select( x => x.Printer.PrintProducts);
But unless you have a very strict performance requirement, it seems better for code readability to just browse to it.
I know if I want to create a multilingual MVC4 application I would use resource files according to CultureInfo, but that would be useful for application's labels, messages, titles..etc, however I was thinking about defining a list of counties' names and their cities in many languages, now should I define them in a resource files (which can be exhausting) or should I use a table with many columns for each language?
And if I used resource files, how can I tell which country a user is from when he register in the system?
Which one is best practice? Is there any other approach?
Using multiple columns for each language will work, but it will also get out of hand pretty quickly as more columns and languages need to be added down the road. So I'd advise against that approach.
What you can do however is move the columns that need to be localized to a different table with a compound primary key. Here's a simple example with a cities table :
You'll have classes that look somewhat like this :
// City.cs
public class City
{
public int CityId { get; set; }
public string UnlocalizedField1 { get; set; }
public string UnlocalizedField2 { get; set; }
// Optional
public virtual List<CityTranslation> Translations { get; set; }
}
// CityTranslation.cs
public class CityTranslation
{
public int CityId { get; set; }
public string LanguageId { get; set; }
public string LocalizedField1 { get; set; }
public string LocalizedField2 { get; set; }
}
Then it becomes rather trivial to query your data in the language you need.
I've been looking for this conundrum for days now and been on many possible solutions, but either the examples are too far removed from what I am attempting and I am just not good enough to take in the data because of it. Hence I decided to ask the question myself and show my particular situation.
I got a product model like this (simplified)
public class Product
{
[Key]
public int ProductId { get; set; }
public string SKU { get; set; }
public int ProductCategoriesId { get; set; }
public bool Purchase { get; set; }
public bool ShowProduct { get; set; }
public virtual IList<ProductTranslations> ProductTranslations { get; set; }
}
public class ProductTranslations
{
[Key]
public int ProductTranslationsId { get; set; }
public int ProductId { get; set; }
public string ProductLanguage { get; set; }
public string Description { get; set; }
public string ProductName { get; set; }
public virtual Product Product { get; set; }
}
So I have one product with language neutral data, then each product can have several child elements, one for each language. I have an edit form where I want to show the language neutral data and the language specific data (names and descriptions).
Simplified view:
#model Artikelhantering.Models.Product
#using (Html.BeginForm())
{
#Html.LabelFor(model => model.SKU)
#foreach (var item in Model.ProductTranslations)
{
#Html.EditorFor(TranslationItem => item.ProductName)
#Html.TextAreaFor(TranslationItem => item.Description)
}
<p>
<input type="submit" value="Save" />
</p>
}
This gets everything onto the view nice and tidy looking I think, I think I could (should?) make a dedicated viewmodel for the editor-view later on. Anyway the problem is I don't know how to update the data on submit. I can update the language neutral data using normal EF approach but any changes to the fields from the other model are unchanged...
And to be honest that makes perfect sense to me, since there's nothing in the form to distinquish them, no unique id's or such and the product model does not contain those fields either... The way I would this in old classic asp would be to name the fields with their unique Id's and then make an SQL update query that updated each child model on submitting the form. I guess I could implement such a practice here too but it doesn't feel like the right way to go about things.
Is there a proper or 'best practices' approach in MVC for this kind of thing?
I'm trying to expand beyond the "one-to-one" mapping of models to controllers to views that most mvc(3) tutorials offer.
I have models for a person (operator) and the person's picture. In the database they would correspond to Operator and OperatorPicture tables.
public class Operator
{
public Operator()
{
this.OperatorPictures = new HashSet<OperatorPicture>();
}
[DisplayName("Operator ID")]
public int OperatorID { get; set; }
[Required]
[DisplayName("First name")]
[StringLength(20, ErrorMessage = "The first name must be 20 characters or less.")]
public string OperatorFirstName { get; set; }
[Required]
[DisplayName("Last name")]
[StringLength(20, ErrorMessage = "The last name must be 20 characters or less.")]
public string OperatorLastName { get; set; }
public virtual ICollection<OperatorPicture> OperatorPictures { get; set; } // Nav
}
public class OperatorPicture
{
[DisplayName("Operator Picture ID")]
public int OperatorPictureID { get; set; }
[DisplayName("Operator ID")]
public int OperatorID { get; set; }
[DisplayName("Picture")]
public byte[] Picture { get; set; } // 100x100
[DisplayName("Thumbnail")]
public byte[] Thumbnail { get; set; } // 25x25
public virtual Operator theoperator { get; set; } // FK
}
In most views I would present them together. A list of operators would include a thumbnail picture if it exists. Another screen might show the person's detailed information along witht the full-sized picture.
Is this where viewmodels come into play? What is an appropriate way to use them?
Thanks,
Loyd
Definitely a time for using them. ViewModels are just a way of packaging up all the different bits that go into a view or partialview.
Rather than have just the repository pattern, I have repositories and services. The service has a Get property called ViewModel, that can be called from the controller. EG:
// initialise the service, then...
return View(service.ViewModel)
You can see a more detailed description of my approach in the accepted answer for the following SO question:
MVC Patterns
Note that I am using dependency injection in that code.
It may not be a totally orthodox or canonical approach, but it results in very clean controller code and a easy to use pattern.