How should I design my database for Point of Sale system? - sql-server

I'm developing a new WPF & MVVM & EF (Code First) application to build a Point of Sale system for one of my customers. I've taken a look to guides on the web and here. But I'm still confusing about how the database design should be?
I've found a good example of the design that I've mentioned which is this project. But I'm kinda worried about the extensibility and quality.
I'm thinking to build the scheme like this:
[Table("Customer")]
public partial class Customer
{
public int CustomerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName => FirstName + " " + LastName;
...
}
[Table("Category")]
public partial class Category
{
public int CategoryId { get; set; }
public string CategoryName { get; set; }
...
}
[Table("Brand")]
public partial class Brand
{
public int BrandId { get; set; }
public string BrandName { get; set; }
...
}
[Table("Product")]
public partial class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
public int CategoryId { get; set; }
public int BrandId { get; set; }
public decimal ListPrice { get; set; }
...
}
[Table("Stock")]
public partial class Stock
{
public int ProductId { get; set; }
public int Quantity { get; set; }
...
}
[Table("Order")]
public partial class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public int OrderStatus { get; set; }
public DateTime OrderDate { get; set; }
...
}
[Table("OrderItem")]
public partial class OrderItem
{
public int OrderId { get; set; }
public int ItemId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal ListPrice { get; set; }
...
}
What kind of problems may arise If I use a scheme like this? Or Is there a point about the scheme I should take care of?

This looks pretty good and simple to me. I have only two comments:
It's common for a product to belong to more than one category. You can achieve this by adding another table relating products to categories.
Stock has a 1:1 relationship with Product, so really you could put the fields for Stock under Product, unless there is something hiding in your "..." that would necessitate them being separated.

Related

EF Core query full join between many-to-many relation

I'm working with EF core and I have a many-to-many relation between STUDENTS and SUBJECTS, like this:
public class StudentDetail
{
[Key]
[JsonPropertyName("Id")]
public int Id { get; set; }
[Required]
[Column(TypeName ="nvarchar(50)")]
[JsonPropertyName("Name")]
public string Name { get; set; }
[JsonPropertyName("StudentSubjects")]
public virtual IEnumerable<StudentSubject> StudentSubjects {get; set;}
}
public class SubjectDetail
{
[Key]
[JsonPropertyName("Id")]
public int Id { get; set; }
[Required]
[Column(TypeName = "nvarchar(20)")]
[JsonPropertyName("SubjectName")]
public string SubjectName { get; set; }
[Required]
[JsonPropertyName("Teacher")]
public virtual TeacherDetail Teacher { get; set; }
[JsonPropertyName("StudentSubjects")]
public IEnumerable<StudentSubject> StudentSubjects { get; set; }
}
public class StudentSubject
{
[JsonPropertyName("StudentId")]
public int StudentId { get; set; }
[JsonPropertyName("Student")]
public StudentDetail Student { get; set; }
[JsonPropertyName("SubjectId")]
public int SubjectId { get; set; }
[JsonPropertyName("Subject")]
public SubjectDetail Subject { get; set; }
[Required]
[Column(TypeName = "nvarchar(3)")]
[JsonPropertyName("Grade")]
public string Grade { get; set; }
}
I create my Databse using migrations, so after I did the migration, the database was created like this:
I need a query that bring me all the Subjects with their teacher and grade of an specific Student. I was tryng doing it like this:
var subjects = await _context.StudentSubject
.Include(s => s.Subject)
.Where(sid => sid.StudentId == student.Id)
.Select(st => st.Subject)
.Include(t => t.Teacher)
.ToListAsync();
But I'm getting an ERROR saying that I'm tryng to use Include(); on a non Queryable Entity. Anyone know what am I doing wrong?
Include will only work if you are having a link between two table and that is defined by keyword Virtual in C# classes. Please use public virtual ICollection instead of public IEnumerable and follow the link for more details. If you still wants to continue with same class then try using join in Linq queries.

I want to make a one-to-one relationship between two columns in ASP.NET Core

I have reading and jobOrder class. I want to create a relationship between joborderId in the jobOrder class and jobOrderId in reading class.
public class JobOrder
{
[Key]
public int Id { get; set; }
public int JobOrderId { get; set; }
public DateTime StartDate { get; set; }
public Nullable<DateTime> EndDate { get; set; }
public string MachineCode { get; set; }
public decimal TotalLength { get; set; }
}
public class Reading
{
public int Id { get; set; }
public string MachineCode { get; set; }
public decimal Length { get; set; }
public bool status { get; set; }
public DateTime time { get; set; }
public int JobOrderId { get; set; }
public JobOrder JobOrder { get; set; }
}
The best way is to take a look at the documentation: https://learn.microsoft.com/en-us/ef/core/modeling/relationships#one-to-one
If you do it the way you described then EF will choose one of the entities to be the dependent based on its ability to detect a foreign key property. If the wrong entity is chosen as the dependent, you can use the Fluent API to correct this.
When configuring the relationship with the Fluent API, you use the HasOne and WithOne methods.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasOne(p => p.BlogImage)
.WithOne(i => i.Blog)
.HasForeignKey<BlogImage>(b => b.BlogForeignKey);
}
If you follow the code first naming conventions EF will automatically discover the Key, ForeignKey and Navigation properties :
public class JobOrder
{
// Primary key (can be JobOrderId as well)
public int Id { get; set; }
// other fields...
// Foreign key
public int ReadingId { get; set; }
// Navigation property
public Reading Reading { get; set; }
}
public class Reading
{
// Primary key (can be ReadingId as well)
public int Id { get; set; }
// other fields...
// Foreign key
public int JobOrderId { get; set; }
// Navigation property
public JobOrder JobOrder { get; set; }
}
If you have more than one key composite keys to create the relationship, you need to manually define the keys and foreign keys:
public class JobOrder
{
[Key]
[Column(Order=1)]
public int Id { get; set; }
[Key]
[Column(Order=2)]
public int JobOrderNo { get; set; }
// other fields...
// Foreign key
public int ReadingId { get; set; }
// Navigation property
public Reading Reading { get; set; }
}
public class Reading
{
public int Id { get; set; }
// other fields...
[ForeignKey("JobOrder")]
[Column(Order=1)]
public int JobOrderId { get; set; }
[ForeignKey("JobOrder")]
[Column(Order=2)]
public int JobOrderNo { get; set; }
// Navigation property
public JobOrder JobOrder { get; set; }
}
How about going like this, it will create 1 to 1 relationship between JobOrder and Reading
public class JobOrder
{
[Key]
public int Id { get; set; }
public int JobOrderId { get; set; }
public DateTime StartDate { get; set; }
public Nullable<DateTime> EndDate { get; set; }
public string MachineCode { get; set; }
public decimal TotalLength { get; set; }
public virtual Reading Reading { get; set; }
}
public class Reading
{
[Key]
[System.ComponentModel.DataAnnotations.Schema.ForeignKey("JobOrder")]
public int Id { get; set; }
public string MachineCode { get; set; }
public decimal Length { get; set; }
public bool status { get; set; }
public DateTime time { get; set; }
public JobOrder JobOrder { get; set; }
}

Error while adding Foreign Key from MVC Models

Here are my Models
[Table("Stationery")]
public class Stationery
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
}
[Table("Orders")]
public class Order
{
[Key]
public int CustomerID { get; set; }
[ForeignKey("Stationery")]
public int ID { get; set; }
public int Quantity { get; set; }
}
On adding controller to Order I am getting following error...
saying that :
Unable to retrieve Metadata for Models.Order. The foreign key attribute on property 'ID' on type 'Models.Order' is invalid. The navigation property 'Stationery' was not found on the dependent type 'Models.Order'. The name value should be a valid navigation property name.
Please Help!!
Thank You.
Create your model like this to add relationship, your both do not know about the relation, this will work if its one to one relation:
[Table("Stationery")]
public class Stationery
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public Order Order {get;set;}
}
[Table("Orders")]
public class Order
{
[Key]
public int CustomerID { get; set; }
[ForeignKey("Stationery")]
public int ID { get; set; }
public int Quantity { get; set; }
public virtual Stationery Stationery { get; set; }
}
if relationship is one to many do like this:
[Table("Stationery")]
public class Stationery
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public ICollection<Order> Orders {get;set;}
}
[Table("Orders")]
public class Order
{
[Key]
public int CustomerID { get; set; }
[ForeignKey("Stationery")]
public int ID { get; set; }
public int Quantity { get; set; }
public virtual Stationery Stationery { get; set; }
}
Try change code like this:
public class Stationery
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
public virtual IList<Order> Orders { get; set; }
}
public class Order
{
[Key]
public int CustomerID { get; set; }
public virtual Stationery Stationery { get; set; }
public int Quantity { get; set; }
}

EF many-to-many

How to build these tables for EF?
First table :
public class model1
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Second table :
public class model2
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Table which has a connection of the first and second
and several fields :
public class model3
{
public int (id from model1){ get; set; }
public int (id from model2) { get; set; }
public int (id from model2){ get; set; }
public decimal Name{ get; set; }
public decimal Description{ get; set; }
}
I think that this may do the trick (provide the table structure you described)
public class model3
{
public virtual model1 Model1 { get; set; }
public virtual model2 Model2 { get; set; }
public virtual model2 SecondModel2 { get; set; }
// if you want the ID fields explicitly,
// EF will map the keys by property name,
// optionaly you can use the ForeignKeyAttribute
public int Model1Id { get; set; }
public int Model2Id { get; set; }
public int SecondModel2Id { get; set; }
public decimal Name{ get; set; }
public decimal Description{ get; set; }
}
But you may want to rethink the structure - the one you presented looks a bit suspicious - model1 and model2 have the same fields, so maybe they shouldn't be defined as separate classes. The model3 class also has some common fields, so maybe it would be worth extracting them into a common class - EF handles inheritance.
To get a many to many relation though, you need something like this:
public class Foo
{
public int Id {get;set;}
public virtual ICollection<Bar> Bars {get;set;}
}
public class Bar
{
public int Id {get;set;}
public virtual ICollection<Foo> Foos {get;set;}
}
this will create a Foo table, a bar table and a FooBars (or BarFoos) associacion table.

Better way to create database for a pricing system

I need to create a price table system so I am going to create these three tables in my database.
PricingTable (ID, Name, ServiceID, Style)
PricingTablePackages (ID, PricingTable_ID, Title, Price, PricePerTime, Info, Flag, Link)
PricingTablePackagesFeatures (ID, PricingTablePackages_ID, Feature, Value, MoreInfo)
Here one PriceTable can hold more then one PricingTablePackages and one PricingTablePackage can hold more then one PricingTablePackagesFeature.
Is any way to design a better model? In a single database Table ?
I am going to create a MVC3 Model for those table so what is the best way to do this kind of DB Table in a MVC3 Model?
I would use public virtual variables for 'lazy-loading' values when you need them using Entity Framework:
(variable types may be off depending on exactly what you want for each variable)
public class PricingTablePackages
{
public int ID { get; set; }
public int PricingTableID { get; set; }
public virtual PricingTable PricingTable { get; set; }
public string Title { get; set; }
public decimal Price { get; set; }
public decimal PricePerTime { get; set; }
public string Info { get; set; }
public bool Flag { get; set; }
public string Link { get; set; }
}
public class PricingTablePackagesFeatures
{
public int ID { get; set; }
public int PricingTableID { get; set; }
public virtual PricingTable PricingTable { get; set; }
public string Feature { get; set; }
public string Value { get; set; }
public string MoreInfo { get; set; }
}
public class PricingTable
{
public int ID { get; set; }
public string Name { get; set; }
public int ServiceID { get; set; }
public virtual Service Service { get; set; } // if there is a Service class
public string Style { get; set; }
}

Resources