I want to notify my MVC Model from Angular Update request, about which property is changed, which property is modified or which property is deleted?
can anyone provide a better solution.
Angular Class:-
export class Customer {
ID?:number;
firstName!: string;
lastName!: string;
email!: string;
emailConfirm!: string;
status!: EntityStatus.Added;
Addresses!: Address[];
}
MVC Model class:-
public partial class Customer
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Customer()
{
this.Addresses = new HashSet<Address>();
}
public int ID { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Address> Addresses { get; set; }
}
EntityState enum same for both Angular & MVC 5 Entity Framework :-
export enum EntityStatus{
Detached = 1,
Unchanged = 2,
Added = 4,
Deleted = 8,
Modified = 16
}
Related
I'm new to Entity Framework and I'm trying to create database for my Android application using Entity Framework with a code-first approach (I think).
My database would look like this:
In the Restaurant table, I would like to have a list of Dish table elements and same for Groceries in the Dish table.
I tried to do it like this:
https://entityframework.net/knowledge-base/41048304/entity-framework-class-with-list-of-object
But I can't see the FK in migration or in the database.
Next I tried it like this code below (here are my classes) :
public class Restaurant
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdRestaurant { get; set; }
[Required]
public String NameOfRestaurant { get; set; }
[Required]
public String Location { get; set; }
[Required]
public String PictureOfRestaurant { get; set; }
public virtual ICollection<Dish> Dishes { get; set; }
[Required]
public String UserId { get; set; }
public ApplicationUser User { get; set; }
}
public class Dish
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdDish { get; set; }
[Required]
public String NameOfDish { get; set; }
[Required]
public String PictureOfDish { get; set; }
[Required]
public Double Price { get; set; }
[Required]
public Double CalorieValue { get; set; }
public virtual int? IdRestaurant { get; set; }
public virtual Restaurant Restaurant { get; set; }
public virtual ICollection<Grocery> Groceries{ get; set; }
[Required]
public String UserId { get; set; }
public ApplicationUser User { get; set; }
}
public class Grocery
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int IdGrocery { get; set; }
[Required]
public String NameOfGrocery { get; set; }
[Required]
public String PictureOfGrocery { get; set; }
[Required]
public Double CalorieValue { get; set; }
public virtual int? IdDish { get; set; }
public virtual Dish Dish { get; set; }
[Required]
public String UserId { get; set; }
public ApplicationUser User { get; set; }
}
But it didn't work.
After I solve this problem, I would like to add some elements in database. Tried it like this (just to test if it works, but with no success) :
internal sealed class Configuration : DbMigrationsConfiguration<Restaurants.Models.MojDbContext>
{
public Configuration()
{
AutomaticMigrationsEnabled = false;
}
protected override void Seed(Restaurants.Models.MojDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data.
context.Groceries.AddOrUpdate(x => x.IdGrocery,
new Grocery()
{
NameOfGrocery = "Carrot",
PictureOfGrocery = "anhnahdagd",
CalorieValue = 55
},
new Grocery()
{
NameOfGrocery = "Tomato",
PictureOfGrocery = "wqeqwewqeewqqew",
CalorieValue = 89
},
new Grocery()
{
NameOfGrocery = "Potato",
PictureOfGrocery = "zuuuiitutuitu",
CalorieValue = 110
}
);
context.SaveChanges();
}
}
And when I add a migration with:
Add-Migration SeedMigration
it just creates a blank migration :
public partial class SeedMigration : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
So how can I add data into the table?
Create foreign key
To create a foreign key, you have to add a line that is an [Index], with a name (in this example) U_FK and then add [Required] at the end.
[Index]
public int U_FK { get; set; } // Foreign Key - User
[Required]
Create list of foreign key
To create a foreign key, you have to add a line that is an [Index], with a name (in this example) U_FK and then add [Required] at the end.
[Index]
public List<int> U_FK { get; set; } // Foreign Key - User List
[Required]
Add elements to database
To add elements you first call the class name and create a new instance of it, in this case exp. Then you assign it's values (as long as they aren't required you don't have to). After that you load your context and save it in ExampleList you created (will show example below).
Example exp = new Example
{
Active = true,
Titel = InputTitel,
Views = 0,
};
using(var context = new ForumDbContext())
{
context.Examples.Add(exp);
context.SaveChanges();
}
Create a Context (if you don't already have one)
In your specific case you can replace Context with your already existing seed migration.
public class GlobalRef
{
public static string dbConnectionString = "Data Source = (localdb)\\MSSQLLocalDB; Initial Catalog = FForumDB; Integrated Security = True; MultipleActiveResultSets=True";
}
public class ForumDbContext : DbContext
{
public ForumDbContext() : base(GlobalRef.dbConnectionString) {}
public DbSet<Example> Examples{ get; set; }
}
Get Value from database
To get for example the ID of another Datatable. You first get the context again. Then you loop through each element in that Database where it's active and order it by views. You can also add .First() to only get the first element that was returned.
using(ForumDbContext context = new ForumDbContext())
{
foreach(Example example in context.Examples.SqlQuery("SELECT * FROM Examples WHERE Active='1' ORDER BY Views" ).ToList<Example>())
{
int exampleid = example.E_ID;
}
}
Get all Values from database and put them in a List
List<int> exampleFKs = new List<int>;
using(ForumDbContext context = new ForumDbContext())
{
foreach(Example example in context.Examples.SqlQuery("SELECT * FROM Examples WHERE Active='1' ORDER BY Views" ).ToList<Example>())
{
exampleFKs.Add(example.E_ID);
}
}
I am writing a Data Access Layer using EntityFramework 6. What I want is that when I invoke the SaveChanges() method on the DbContext, it will save the entity together with the set of relevant entities associated via navigation properties. Following is the simple code I am trying to do.
public class Customer
{
public long ID { get; set; }
public string Name { get; set; }
public virtual IEnumberable<PhoneNumber> { get; set; }
}
public class PhoneNumber
{
public long ID { get; set; }
public string Number { get; set; }
}
public class SampleContext : DbContext
{
public virtual DbSet<Customer> Customers { get; set; }
public virtual DbSet<PhoneNumber> PhoneNumbers { get; set; }
}
using(var context = new SampleContext())
{
var customer = new Customer { ID = 1, Name = "John" };
customer.PhoneNumbers = new PhoneNumbers[]
{
new PhoneNumber { ID = 1, Number = "1.111.1111111" },
new PhoneNumber { ID = 2, Number = "1.111.1111112" }
}
context.Customers.Add(customer);
context.SaveChanges();
}
The above code saves the customer in the customers table but saves nothing in the PhoneNumbers table.
Strange but found a solution. The above code need a little modification to make it work. Followings are the modifications:
//In Customer class, changed following line:
public virtual IEnumberable<PhoneNumber> { get; set; }
//To:
public virtual ICollection<PhoneNumber> { get; set; }
//Then in using block initialized entities as follows:
using(var context = new SampleContext())
{
var customer = new Customer { ID = 1, Name = "John", PhoneNumbers = new List<PhoneNumber>() };
customer.PhoneNumbers.Add(new PhoneNumber { ID = 1, Number = "1.111.1111111" });
context.Customers.Add(customer);
context.SaveChanges();
}
I have a model with 2 subclasses:
public class User
{
public string eRaiderUsername { get; set; }
public int AllowedSpaces { get; set; }
public ContactInformation ContactInformation { get; set; }
public Ethnicity Ethnicity { get; set; }
public Classification Classification { get; set; }
public Living Living { get; set; }
}
public class Student : User
{
public Student()
{
AllowedSpaces = AppSettings.AllowedStudentSpaces;
}
}
public class OrganizationRepresentative : User
{
public Organization Organization { get; set; }
public OrganizationRepresentative()
{
AllowedSpaces = AppSettings.AllowedOrganizationSpaces;
}
}
public class ContactInformation
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string EmailAddress { get; set; }
public string CellPhoneNumber { get; set; }
}
public enum Ethnicity
{
AfricanAmerican,
AmericanIndian,
Asian,
Black,
Hispanic,
NativeHawaiian,
NonResidentAlien,
White
}
public enum Classification
{
Freshman,
Sophomore,
Junior,
Senior,
GraduateStudent
}
public enum Living
{
OnCompus,
OffCampus
}
This is (mostly) saving fine using these initializers:
var students = new List<Student>
{
new Student{ eRaiderUsername="somestudent", ContactInformation=new ContactInformation{FirstName="Some", LastName="Student", EmailAddress="student#example.com", CellPhoneNumber="1234567890"}, Classification=Classification.Junior, Ethnicity=Ethnicity.Hispanic, Living=Living.OffCampus }
};
students.ForEach(s => context.Users.Add(s));
context.SaveChanges();
var orgReps = new List<OrganizationRepresentative>
{
new OrganizationRepresentative{ eRaiderUsername="somerep", ContactInformation=new ContactInformation{FirstName="Some", LastName="Representative", EmailAddress="orgrep#example.com", CellPhoneNumber="0987654321"}, Classification=Classification.Freshman, Ethnicity=Ethnicity.White, Living=Living.OnCompus, Organization=context.Organizations.Find(1) }
};
orgReps.ForEach(o => context.Users.Add(o));
context.SaveChanges();
None of the enums are saving (advice on this would be awesome too). But everything else is saving fine.
I have noticed Entity has added a Discriminator column with the subclass names. How do I use this to query only students, only organization reps, or just tell if the current object is a student or organization rep in a controller or view?
The discriminator column is used internally by EF to determine the type of object to instantiate.
For example you could query for a student directly. context.Set<Student>.Find(id). The same is true for an org rep. Or you could query for any user context.Set<User>.Find(id).
If you query for a student, but pass an org rep's ID, then EF will return null, because the ID doesn't belong to a student.
Models in question:
public class EmployeeType
{
public int employeeTypeId { get; set; }
public string typeName { get; set; }
public virtual List<Employee> Employees { get; set; }
}
public class Employee
{
public int employeeId { get; set; }
public string userName { get; set; }
public string firstName { get; set; }
public string lastName { get; set; }
public string password { get; set; }
public int employeeTypeId { get; set; }
public virtual EmployeeType EmployeeTypes { get; set; }
public virtual List<PhoneNumber> PhoneNumbers { get; set; }
}
At the moment i am adding different values through:
db.EmployeeType.Add(new EmployeeType
{
typeName = "Administrator"
});
db.EmployeeType.Add(new EmployeeType
{
typeName = "Seller"
});
db.EmployeeType.Add(new EmployeeType
{
typeName = "Accountant"
});
But in a case when i have to check if the user is an administrator or etc. i have to check through linq query and find out if the id is equal to the id in the Employee table.
How could i define default records in the EmployeeType model and not add the values through multiple .Add lines, so that i could use something like this:
if (db.Employee.FirstOrDefault(o => ...).servictypeId
== EmployeeType.Administrator)
{
}
The best way to handle this would be to convert employeetypeId into an enum in EF. You can easily achieve this by "converting" the field into an enum within the EDMX. Just right click on the property in the edmx model design screen and click "convert to enum".
Firstly though, you need to create an Enum, Called UserRole :-
enum UserRole : int
{
Administrator = 1,
Manager = 2,
Client = 3
}
Now, when you want to make new UserRole's you add them in your Enum.
When it comes to adding a new user, you simply do the following :-
new User object1 { Name = "Fred", UserRole = UserRole.Client};
dbContext.Save(object1);
EF will know to save the employeeTypeId as 3 in the database.
The advantage gets better, because now you can say :-
if(User.UserRole == UserRole.Adminstartor)
{
//Do Stuff
}
Maybe a simple question, but I can't seem to figure it out. Saving a collection to a model when adding a model to the database isn't working. I have a site which uses asp.net MVC and entity framework.
The models:
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public ICollection<EventRange> Ranges { get; set; }
}
public class EventRange
{
public int Id { get; set; }
public string RangeName { get; set; }
public string RangeDescription { get; set; }
public int Capacitiy { get; set; }
}
The controller actions:
[HttpPost]
public ActionResult Create(Event model)
{
ICollection<EventRange> eventRanges = new Collection<EventRange>();
var range = new EventRange {RangeName = "testrange", RangeDescription = "test", Capacitiy = 5}
eventRanges.Add(range);
model.Ranges = eventRanges;
db.Events.Add(model);
db.SaveChanges();
return View();
}
public ActionResult Events()
{
return View(db.Events);
}
When setting a breakpoint in the Events action and evaluated the query, the Range isn't saved to the event:
Code Screenshot
Note that that the database created for the eventrange model by EF does save the range:
EF DB Screenshot
Am I doing something wrong?
What if you mark the Ranges property as virtual?
public virtual ICollection<EventRange> Ranges { get; set; }