We have the following table structure
Person
--ID (PK)
--NAME
Bank Account
P_ID (FK - Person.ID)
Name
Number
RichPerson
P_ID (FK - Person.ID
Age
..other fields
(primary key (P_ID, Age)
What we are trying to achieve is to load the bank accounts for RichPerson
i.e.
class RichPerson
{
public int P_ID {get;set;}
public int Age {get;set;}
public List<BankAccount> accounts;
}
class Person {
public int ID {get; set;}
public string Name {get;set;}
}
class BankAccount {
public int P_ID {get;set;}
public string Name {get; set;}
public int Number {get;set;}
/* No navigation property is a requirement */
}
We have tried various options but cant figure out the association mapping that would go here,
in the entitytypeconfiguraiton we currently have
public class RichPersonMap : EntityTypeConfiguration<RichPerson> {
...
this.HasKey(t => new { t.P_ID, t.Age });
...
this.HasMany(x => x.accounts)
.WithOptional()
.Map(/* WHAT GOES HERE */);
}
Related
I have a "nested" Entity Framework model structure. Here are my models:
class Parent
{
public int ParentId {get;set;}
virtual ICollection<Child> children {get;set;}
}
class Child
{
public int ChildId {get;set;}
public Parent Parent {get;set;}
virtual ICollection<Account> accounts {get;set;}
}
class Account
{
public int AccountId {get;set;}
public Child Child {get;set;}
public string SomeProperty {get;set;}
}
class DbContext
{
public DbSet<Parent> parents {get;set;}
public DbSet<Child> children {get;set;}
public DbSet<Account> accounts {get;set;}
}
How do I change the Account.SomeProperty for all Accounts belonging to a certain Parent with minimal DB queries?
How about this
var db = new DbContext();
var accounts = db.accounts.Where(a => a.Child.Parent.ParentId == parentId);
foreach (var account in accounts)
{
account.SomeProperty = ...;
}
db.SaveChanges();
It will generate just one query (with necessary joins) to retrieve "all Accounts belonging to a certain Parent". How many update statements will be generated is out of your control.
With Code first i've the following :
public class Key
{
[Key, Column(Order=0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key, Column(Order = 1)]
public int CompanyId { get; set; }
}
public class Employee : Key
{
public string Name { get; set; }
public string Job { get; set; }
}
public class Department : Key
{
public string DepName { get; set; }
}
Public class Context : DbContext
{
Public Context() : base("name:DefaultConnection")
{
}
Public DbSet<Employee> Employees {get; set;}
Public DbSet<Department> Departments{get; set;}
}
This code first generates for me two tables only in the database, Employee table with two primary keys (Id, CompanyId) inherited from class Key, and Department table with two primary keys (Id, CompanyId) inherited from class Key.
I lost hours trying to do the same behavior using model first approach but i couldn't.
I'll appreciate if any Entity framwork professional can help with that :)
I have created a model in the name of Sample with an Id and DocumentId property.In this I don't mention primary key for Id property.But it forms the primary key when I created the Sample as table in entity framework.I want to remove the primary key for Id. What do I have to do. Please help me. I am very new to mvc4.
public class Sample
{
[Required,DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
[Required]
public int DocumentId { get; set; }
}
public override void Up()
{
CreateTable(
"dbo.Samples",
c => new
{
Id = c.Int(nullable: false, identity: false),
DocumentId = c.Int(nullable: false),
})
.PrimaryKey(t => t.Id);
}
I am putting this here as I don't think it will show up very well in comments :)
In the case of a user having many roles (and each role possibly being played by many users), you would have three tables linked to 2 classes. The tables would be a Users table with a unique UserId column and the rest of the user details. Another table would be Roles with a unique RoleId and the rest of the role information and a joining table that would have the id of the user and the id of the role he plays (this table could have a unique id of itself). If the user has 2 roles, they would have 2 records in the joining table, one for each of the roles. The classes would look something like this:
public class User{
public long UserId {get;set;}
public ICollection<Role> roles{get;set;}
//Other properties of the user name, DOb,etc.
}
public class Role{
public long RoleId{get;set;}
public ICollection<User> Users{get;set;}
//other properties of Role
}
This is a many to many relationship. Of course you could also have it as a one to many relationship if the role can be played by one user. In that case you don't need the joining table and you can just add a UserId column to the Role table and instead of a collection of users, the role would have a single property of type user (not really needed unless you want to navigate back from role to user).
Try adding the NotMapped attribute in your Id.
public class Sample
{
[Key]
public int SampleId {get;set;}
[Required,DatabaseGenerated(DatabaseGeneratedOption.None)]
[NotMapped]
public int Id { get; set; }
[Required]
public int DocumentId { get; set; }
}
EDIT:
I added a key attribute to specify your primary key.
You can also try this, which I think is better:
public class Sample
{
public int SampleId {get;set;}
public virtual ICollection<Document> Documents {get;set;}
}
public class Document
{
public int DocumentId {get;set;}
public int SampleId {get;set;}
public virtual Sample Sample {get;set;}
}
virtual keyword is for lazy loading.
Open the entity diagram (.edmx) file and find which ever property in that particular table is the primary key. Right click on it and select "properties". In the properties window see where it says StoreGeneratedPattern - Identity? Change that to none and save the diagram. It will regenerate the .cs model files by itself
Fluent API suppresses the Data Annotations in Entity framework. Data Annotation for Primary is [Key] and ID is by default Primary key with identity.
In that scenario, Delete(if it's there) Data Annotation of ID i:e;[KEY] and use Fluent API in your context class. In below example, my primary key is "CustomerName" due to Fluent. Example:
public class Customer
{
public int CustomerName { get; set; }
public int ID { get; set; }
[Required]
public string ProductID { get; set; }
}
In Context Class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>().HasKey(s => s.CustomerName);
}
I have three models for Province, District & Village. I also have a model for Employee.
the Employee Model:
public class Employee {
public int EmployeeId {get;set;}
public string FullName {get;set;}
public int VillageId {get;set;}
}
the Province Model:
public class Province{
public int ProvinceId {get;set;}
public string Name {get;set;}
}
the District Model:
public class District{
public int DistrictId{get;set;}
public string Name {get;set;}
public int ProvinceId {get;set;}
public virtual Province province {get;set}
}
The Village Model:
public class Village{
public int VillageId{get;set;}
public string Name {get;set;}
public int DistrictId {get;set;}
public virtual District district {get;set}
}
Now i want my employee strongly typed view to have three drop down lists and when i select a province, then the district drop down list must be filled with those districts that are in the selected province and when i select a district the village drop down list must be populated with the villages that are in the selected district.
The village drop down should be of strongly type dropdown list.
The following examples show how to create cascading dropdownlists with strongly typed helpers.
http://www.codeproject.com/Articles/258172/Simple-Implementation-of-MVC-Cascading-Ajax-Drop-D
http://www.dotnetpools.com/Article/ArticleDetiail/?articleId=169&title=MVC3-Cascading-DropdownList-Using-Jquery
http://www.deliveron.com/blog/post/Creating-a-Cascading-Dropdown-in-ASPnet-MVC-3-and-jQuery.aspx
I am developing a CMS and I have a category class like this :
public partial class Category
{
public int CategoryId {get;set;}
public string CategoryName {get;set;}
public string CategoryType {get;set;}
}
I am using Entity Framework to store & create such database table in my database. Now, how can I add dynamic fields to this model and hence to the database. I am allowing the user to add his desired custom fields to be added.
So, my database schema becomes
Category(CategoryId, CategoryName, CategoryType, CustomField1, CustomField2);
How can I do this using EF 5?
You can't in the way you expect it. Instead of adding custom fields to Category table you need something like CategoryExtension table where you will store CategoryId, FieldName and FieldValue (key-value pairs related to specific category record) where CategoryId will be FK to Category table and for example CategoryId and FieldName will build composite PK. Your classes will then look like:
public partial class Category
{
public int CategoryId {get;set;}
public string CategoryName {get;set;}
public string CategoryType {get;set;}
public virtual ICollection<CategoryExtension> Extensions { get; set; }
}
public class CategoryExtension
{
public int CategoryId { get; set; }
public string Name { get; set; }
public string Value { get; set; }
}