Creating a score sheet in SQL - sql

On my website, I have a score sheet that the user fills out. They will USUALLY have 10 items on a score sheet and each item will have its own score. I am wanting to design this in the best way for future expandability. What If I want to have more or less items on the score sheet in the future?
Here is what I have now:
public class Scoresheet712Item
{
public int ScoresheetItemId { get; set; }
public int ScoresheetId { get; set; }
public int DistanceAway { get; set; }
public int score { get; set; }
}
Is it better to do this or is it better to have all 10 scores and distances on the same row? I would rather have them in the same row because I can pull that one row directly in as a model. I originally thought to do it this way so I could easily vary how many slots there are on the score sheet, but it doesn't seem like there is much benefit really, specifically because I am using MVC development and I will always need the entire score sheet.
Please help, can I have all the data in one row for a score sheet and that be good practice?
Here is what I am trying to propose, it would be a little different though because each score DOES have a different purpose.:
public class Scoresheet
{
public int ScoresheetId { get; set; }
public int DistanceAway1 { get; set; }
public int score1 { get; set; }
public int DistanceAway2 { get; set; }
public int score2 { get; set; }
public int DistanceAway3 { get; set; }
public int score3 { get; set; }
public int DistanceAway4 { get; set; }
public int score4 { get; set; }
public int DistanceAway5 { get; set; }
public int score5 { get; set; }
public int DistanceAway6 { get; set; }
public int score6 { get; set; }
public int DistanceAway7 { get; set; }
public int score7 { get; set; }
public int DistanceAway8 { get; set; }
public int score8 { get; set; }
public int DistanceAway9 { get; set; }
public int score9 { get; set; }
public int DistanceAway10 { get; set; }
public int score10 { get; set; }
}
Like this?
public class Scoresheet712
{
public int Scoresheet712ID { get; set; }
public virtual ICollection<Scoresheet712Item> Scoresheet712Items { get; set; }
}

I am inclined to agree with #Stephen Muecke to be flexible and extendable you really need two sql tables.
public class Scoresheet
{
public int ScoresheetId { get; set; }
public string ScoresheetName { get; set; }
public ICollection<ScoresheetItem> ScoresheetItems { get; set; }
}
And
Public class ScoresheetItem
{
public int ScoresheetItemId { get; set; }
public int Score { get; set; }
public int Distance { get; set; }
//Navigation properties
public int ScoresheetId { get; set; }
public Scoresheet Scoresheet { get; set; }
{
This will let you build a new Scoresheet as needed with as many or as few items as you want. The example below shows the usage.
//Create a new Scoresheet
Scoresheet scoresheet712 = new Scoresheet()
{
ScoresheetName = "Score Sheet 712",
ScoresheetItems = new List<ScoresheetItem>()
};
//Add a ScoresheeItem to Scoresheet
scoresheet712.ScoresheetItems.Add(new ScoreSheetItem()
{
Score = 10,
Distance = 150
});
Remember that on your View you do not need to use your Data Model you can always add a Data Transfer Object (Scoresheet_DTO) and make the flat structure for your score sheet if it really does make displaying it easier/better, just be sure to use nullable integers.
UPDATE MANY-TO-MANY RELATIONSHIP
For a many-to-many relationship if setup correctly in code it will automatically create the joining table. The Scoresheet class would remain the same but the ScoresheetItem class would have a small change to the Relationship/Navigation properties.
Public class ScoresheetItem
{
public int ScoresheetItemId { get; set; }
public int Score { get; set; }
public int Distance { get; set; }
//Navigation properties
public ICollection<Scoresheet> Scoresheet { get; set; }
{
For further help I would recommend taking a look at this Entity Framework Tutorial

Related

How to establish one-to-many relationship for a code-first approach?

I'm trying to build a recipe app for my spouse. I'm trying to set it up so she can add new recipes to the database as the app grows.
When adding new recipe, she will have three drop-down to pick from to construct her new recipe ingredients. First one will contain a list of ingredients that she can choose from, the second one a list of measuring units and the third one a list of quantities.
Here is what I got so far. Am I heading in the right direction or am I off? I'm using Entity Framework with a code-first approach:
public class Recipes
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Image { get; set; }
}
public class Units model
{
[Key]
public int Id { get; set; }
public string UnitName { get; set; }
}
public class UnitQty
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class IngredientsModel
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class RecipeIngredients
{
public int Id { get; set; }
public int RecipesId { get; set; }
[ForeignKey("RecipesId")]
public Recipes Recipes { get; set; }
public int IngredientsModelId { get; set; }
[ForeignKey("IngredientsModelId")]
public IngredientsModel IngredientsModel { get; set; }
public int UnitQtyId { get; set; }
[ForeignKey("UnitQtyId")]
public UnitQty UnitQty { get; set; }
public int UnitsModelId { get; set; }
[ForeignKey("UnitsModelId")]
public UnitsModel UnitsModel { get; set; }
}
After creating the table, controller and the views, this is what I get in the recipe ingredients index view.
Any suggestion will be more than welcome please and thank you
RecipeIngredient class's view
First of all. You are over engineering your domain model. On relational databases Join is bottleneck you should prevent from joins if it doesn't helps you.
public class Recipt
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Image { get; set; }
public ICollection<RecipeIngredient> Ingredients { get; set; }
}
public class IngredientModel
{
public int Id { get; set; }
public string Name { get; set; }
public IngredientUnit UnitType { get; set; } // Unit model is best to be added here. if it doesn't change in a single IngredientModel.
}
public class RecipeIngredient
{
public int Id { get; set; }
public int UnitQuantiy { get; set; } // No need to more classes.
public IngredientModel Model { get; set; }
public Recipt Recipt { get; set; }
}
public Enum IngredientUnitType // Same Unit Model but less database relation as its small finite collection.
{
Killogram,
Count,
....
}
and according to the Microsoft documents its best to use fluentApi configuration for the relations.
Override this method in your Context:
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Recipt>.HasMany(P => P.Ingredients).WithOne(P => P.Recipt);
builder.Entity<RecipeIngredient>.HasOne(P => P.Model);
// There is no need to explicit foreign key definition. but you can explicitly define your foreign keys.
}
And for the last part. in Views you can use extra models called ViewModels.
As above domain turned to a minimal domain you just need to pass a list of IngredientModels to your view to complete your View.

Is it possible to create a Domain Class which has Multiple FK Columns to same PK?

I'm a newbie to designing database.
I have problem how to define a domain class which has multiple foreign keys linked with a same primary key.
Here is my model:
namespace OceanFmsSystem.Domain
{
public class ExportTemplate
{
public int Id { get; set; }
public List<ExportBooking> ExportBookings { get; set; }
public string TemplateName { get; set; }
public int CustomerId { get; set; }
public string Incoterms { get; set; }
public string IncotermsDetail { get; set; }
public string PaymentTerm{ get; set; }
public int CountryOriginId { get; set; }
public int CountryDestinationId { get; set; }
}
}
What I want to do is that CountryOriginId & CountryDestinationId should refer to the below class as foreign keys:
namespace OceanFmsSystem.Domain
{
public class Country
{
public int Id { get; set; }
public string CountryCode { get; set; }
public string CountryName { get; set; }
}
}
As far as I know, in EF Core there is an convention which I should name a foreign key as below for migration from code to database.
public type ClassNameOfPrimaryKeyId { get; set;}
Is there any possible way to make this happens?
Yes, possible. Your class should look like this:
public class ExportTemplate
{
//...
public int CountryOriginId { get; set; }
public Country CountryOrigin { get; set; }
public int CountryDestinationId { get; set; }
public Country CountryDestination { get; set; }
}
EF is smart enough to figure the Ids by convention. If you do not wish to follow the convention you can use [ForeignKey] attribute on the properties to configure the FK:
[ForeignKey("Origin")]
public int MyOriginId { get; set; }
public Country Origin { get; set; }

How to create a history model of a specific model on MVC 4

I'm still new in creating Models using Entity Framework and MVC 4 Razor. I'm having a problem on how can I save a history of a model. How can I create a model that have a history on specific tables or fields ? For ex: If I wish to create a history on the changes on the school. Its still not clear to me how will I I create the model that saves history. How will be the triggering do I have to execute the save function on different models with the same data ?
Thank you so much in advance.
If anyone could be a simple example of model and a model history and how it is functioning, I'll be very grateful. Like a Sales or sales history.
Here's my code
One To Many
public class Child
{
[Key]
public int ChildID { get; set; }
[Required,Display(Name="Project Code")]
public string ProjectCode { get; set; }
public string Status { get; set; }
[DataType(DataType.Date)]
public DateTime StatusDate { get; set; }
public string FamilyName { get; set; }
public string GivenName { get; set; }
public string MiddleName { get; set; }
[DataType(DataType.Date)]
public DateTime Birthdate { get; set; }
public string Gender {get;set;}
public string Address { get; set; }
public string Section { get; set; }
public int SchoolLevelID { get; set; }
public int SchoolYearID { get; set; }
public int AreaID { get; set; }
public int SchoolID { get; set; }
public int GradeLevelID { get; set; }
//Foreign Key - One to Many
public virtual SchoolLevel SchoolLevel { get; set; }
public virtual SchoolYear SchoolYear { get; set; }
public virtual Area Area { get; set; }
public virtual School School { get; set; }
public virtual GradeLevel GradeLevel{get;set;}
//Child is foreign key at the table
public virtual ICollection<Guardian> Guardians { get; set; }
}
public class SchoolLevel
{
public int SchoolLevelID { get; set; }
public string SchoolLevelName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class SchoolYear
{
public int SchoolYearID { get; set; }
public string SchoolYearName { get; set; }
public virtual ICollection<Child> Children{get;set;}
}
public class Area
{
public int AreaID{get;set;}
public string AreaName { get; set; }
public virtual ICollection<Child> Children{get;set;}
}
public class School
{
public int SchoolID { get; set; }
public string SchoolName{get;set;}
public virtual ICollection<Child> Children { get; set; }
}
public class GradeLevel
{
public int GradeLevelID{get;set;}
public string GradeLevelName { get; set; }
public virtual ICollection<Child> Children { get; set; }
}
public class ChildDbContext : DbContext
{
public DbSet<Child> Children { get; set; }
public DbSet<SchoolLevel> SchoolLevels { get; set; }
public DbSet<SchoolYear> SchoolYears { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<School> Schools { get; set; }
public DbSet<GradeLevel> GradeLevels { get; set; }
public DbSet<Guardian> Guardians { get; set; }
}
You can use this approach: Create a History model. That contains 1 changeness like o log.
public class History
{
public int HistoryId { get; set; }
public int ModelType { get; set; } //it is ModelTypeEnum value.
public int ModelId { get; set; }
public string PropertyName { get; set; }
public string Propertyvalue {get;set;}
public DateTime ChangeDate { get; set; }
public int ChangedUserId { get; set; }
}
And Enum:
public enum ModelTypeEnum
{
Child =1,
SchoolLevel = 2,
//etc..
};
For example, when you edit 1 Child entity, give changed properties name and value, it's id, type and others (ChangeDate, ChangedUserId) to History and save histories. If 3 properties will change you should save 3 history entities. Then, you can load (filter) histories by ModelId, by ChangedUserId etc.

ASP.NET MVC ViewModel is null on Post Back - sometimes

depending on my input in an HTML form (6 or 6.5 - or in general, integer VS float) I get or don't get the following exception (it works with int and doesn't work with float):
The model item passed into the dictionary is null, but this dictionary requires a non-null model item of type 'System.Boolean'.
The ViewModel of my View is null and the problem gets visible in a custom template which expects a bool value, but gets null instead. We use ASP.NET MVC 4 with .Net 4.0, C# and Razor Templates.
After several hours debugging I came to the following conclusion(s):
Post Form-Data are identical (except the one property which is different, but still look correct)
The execution order is somehow weirdly different:
for int I get Application_BeginRequest->Filter which runs through my attributes->Action->View Rendering OR Redirect (everything Normal)
for float I get Application_BeginRequest->Filter which runs through my attributes->View Rendering->END WITH AN EXCEPTION and Empty ViewModel
I have checked it dozen times -> If I pass float the View somehow gets rendered without any Action (which I would have seen) to be executed (and of course the breakpoints were the same all the time). Unfortunately I couldn't see anything in the StackTrace anymore once the View got rendered.
the ViewModel of my View is:
public class JabCommonViewModel
{
public int JAB_ID { get; set; }
[UIHint("Checkbox")]
public bool JAB_gesperrt { get; set; }
[UIHint("Checkbox")]
public bool JAB_Kontrolliert { get; set; }
public int e001 { get; set; }
public string e002 { get; set; }
public int e005 { get; set; }
[UIHint("Checkbox")]
public bool e013 { get; set; }
public bool e014 { get; set; }
public short? e015 { get; set; }
public bool? e149 { get; set; }
public int? e649 { get; set; }
public int? e310 { get; set; }
public int? LastJabe311 { get; set; }
public int jabIdE013 { get; set; }
public int jabIdPrev { get; set; }
public int updCnt { get; set; }
public int checks { get; set; }
public bool calculateInEur { get; set; }
public FormViewModel AktivaPassiva { get; set; }
public FormViewModel GuV1GuV2 { get; set; }
public FormViewModel GuV3 { get; set; }
public ActsFormViewModel ActsForm { get; set; }
public CommonDataViewModel CommonDataForm { get; set; }
public CompanyHeadViewModel CompanyHeadForm { get; set; }
public FacilitiesOverviewModel FacilitiesOverview { get; set; }
}
public class FormViewModel
{
public string ShowAllCaption { get; set; }
public string HideAllCaption { get; set; }
public string CurrentCaption { get; set; }
public string PreviousCaption { get; set; }
public bool HasPreviousData { get; set; }
public IEnumerable<FieldViewModel> Fields { get; set; }
public FormViewModel()
{
Fields = new FieldViewModel[0];
}
}
public class FieldViewModel
{
public string Name { get; set; }
public string Title { get; set; }
public object Value { get; set; }
public bool IsDisabled { get; set; }
public bool IsCollapsible { get; set; }
public bool IsSpecialCase { get; set; } // used currently to expand/collapse groups on second level
public FieldViewModel Previous { get; set; }
public Category DataCategory { get; set; }
public IEnumerable<FieldViewModel> Related { get; set; }
public FieldViewModel()
{
Related = new FieldViewModel[0];
}
public FieldViewModel(string name, string title, object value, bool isDisabled, Category dataCategory = Category.None, bool isCollapsible = true)
{
Name = name;
Title = title;
Value = value;
IsDisabled = isDisabled;
DataCategory = dataCategory;
IsCollapsible = isCollapsible;
Related = new FieldViewModel[0];
}
}
....
The Post-Back Action is
public ActionResult Edit(JAB2 jab)
{
ComponentFactory.Logger.Debug("Edit with JAB2");
....
}
public class JAB2 : JAB
{
public int jabIdE013 { get; set; }
public JAB LastJab { get; set; }
public int checks { get; set; }
}
public class JAB : BaseModel
{
public JAB()
{
}
public bool e116 { get; set; }
public bool e117 { get; set; }
public bool e118 { get; set; }
public bool e119 { get; set; }
public bool e120 { get; set; }
public bool e121 { get; set; }
public bool e122 { get; set; }
public bool e123 { get; set; }
public bool e124 { get; set; }
public bool e125 { get; set; }
public short? e126 { get; set; }
... /* 100 more properties */ ...
[LocalizedDisplayName("e751", NameResourceType = typeof(Resources.ModelPropertyNames))]
public float? e751 { get; set; } /* the property which works as int but not as float */
}
The Post-Back is actually to the link
/JAB/Edit/
Still the correct method get's executed when e751 (the special property) has an integer value.
Also we use the autoNumeric-JavaScript Plugin on that field. Also we use the plugin with other fields but so far found the error only with this one. As well, we have one Workstation where we aren't able to reproduce the error so it occurs on 2 out of 3 workstations + test server.
So far, nothing I've found explains the fact that it works sometimes.
Thank you very much for taking the time and reading my post.
Do you have any Ideas what could be wrong or what I could check?

How does one get row data from a Silverlight DataGrid?

In Silverlight, how does one get row data from a DataGrid that is full of data?
I have gotten this far (in a method that receives a button click on a row(:
DataGridRow item = (DataGridRow)dg.SelectedItem;
Now, how do I get the individual components of the item that I guess is the selected row?
Help me out here. How do you bind an observablecollection to the grid?
How do you use the cast system when you cast to the object?
When I read the data into the grid, I used this class:
public class Data
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
public bool Available { get; set; }
public int index_1 { get; set; }
public int index_2 { get; set; }
public int index_3 { get; set; }
public int index_4 { get; set; }
public int index_5 { get; set; }
public int index_6 { get; set; }
public int index_7 { get; set; }
public int index_8 { get; set; }
public int index_9 { get; set; }
public int index_10 { get; set; }
public int index_11 { get; set; }
public int index_12 { get; set; }
public int index_13 { get; set; }
public int index_14 { get; set; }
public int index_15 { get; set; }
}
So how so I cast when I read back out
This does not work:
Data _mydata = new Data();
YValue = (_mydata.index_1)dg.SelectedItem;
This does not work:
YValue = (index_1)dg.SelectedItem;
This does not work:
YValue = (Data().index_1)dg.SelectedItem;
DataGridRow item = (DataGridRow)dg.SelectedItem;
int index1 = ((Data)item).index_1;
That will give you the value of the first index.
If you have bound a ObservableCollection<Foo> to your grid, your selected item can just be cast into your object - (Foo)dg.SelectedItem
EDIT-- UPDATE TO ANSWER UPDATED QUESTION
The simple answer is, if you are not using MVVM (which I assume by your post your not), in the code behind create a collection (preferably ObservableCollection) of Data and set the grids itemsource property to your collection
public ObservableCollection<Data> MyCollection{get;set;}
void SetGridItemsSource()
{
// populate your collection here, then use the below line to associate it with your
// grids itemssource
MyGrid.ItemsSource = MyCollection;
}
public void GetSelectedItem()
{
//Simply cast the selected item to your type
Data selectedItem = (Data)MyGrid.SelectedItem;
}