View Code
publicclass MyDomainContext : DbContext { public DbSet<Order> Orders { get; set; } public DbSet<OrderDetail> OrderDetails { get; set; } static MyDomainContext() { Database.SetInitializer<MyDomainContext>( new DropCreateDatabaseIfModelChanges<MyDomainContext>()); } }
2.覆盖默认约定 Override Default Naming Convention
1.The model-blocking Builder
rewrite the OnModelCreating
View Code
protected override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); // Map schemas modelBuilder.Entity<Order>().ToTable("efdemo.Order"); }
API
View Code
modelBuilder.Entity<Order>().Property(x => x.OrderID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity) .IsRequired() .HasColumnName("TheOrderID");
rewrite default naming convention
View Code
// Map schemas modelBuilder.Entity<Order>().ToTable("efdemo.Order"); // Identity Column modelBuilder.Entity<Order>().Property(x => x.OrderID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); // String columns modelBuilder.Entity<Order>().Property(x => x.OrderTitle) .IsRequired() .HasMaxLength(64); modelBuilder.Entity<Order>().Property(x => x.CustomerName) .IsRequired() .HasMaxLength(32); // Date Columns modelBuilder.Entity<Order>().Property(x => x.TransactionDate) .IsRequired();
2.Increase the model of the label
View Code
public class Order { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public int OrderNumber { get; set; } … }
3.Greedy load and Lazy load
View Code
var orders = from o in context.Orders.Include("OrderDetails").Include("Businesses") where o.CustomerName == "Mac" select o;
View Code
public class Order { public int OrderID { get; set; } public string OrderTitle { get; set; } public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } public virtual List<OrderDetail> OrderDetails { get; set; } public virtual List<Business> Businesses { get; set; } }
4. Complex Type
1. publicclass Client { publicint ClientID { get; set; } [Required] [StringLength(32, MinimumLength=2)] publicstring ClientName { get; set; } public Address ResidentialAddress { get; set; } public Address DeliveryAddress { get; set; } } publicclass Address { [Required] publicint StreetNumber { get; set; } [Required] [StringLength(32, MinimumLength=2)] publicstring StreetName { get; set; } } 2. protectedoverridevoid OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity<Client>().Property(x => x.ClientID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity); modelBuilder.ComplexType<Address>(); modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetNumber).HasColumnName("ResStreetNumber"); modelBuilder.Entity<Client>().Property(i => i.ResidentialAddress.StreetName).HasColumnName("ResStreetName"); modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetNumber).HasColumnName("DelStreetNumber"); modelBuilder.Entity<Client>().Property(i => i.DeliveryAddress.StreetName).HasColumnName("DelStreetName"); } 3. using (var context1 =new MyDomainContext()) { var client =new Client { ClientName ="Joe", ResidentialAddress =new Address { StreetNumber =15, StreetName ="Oxford" }, DeliveryAddress =new Address { StreetNumber =514, StreetName ="Nolif" } }; context1.Clients.Add(client); context1.SaveChanges(); } using (var context2 =new MyDomainContext()) { var clients = from w in context2.Clients where w.ClientName =="Joe" select w; foreach (var client in clients) { Console.WriteLine("client residential StreetNumber: "+ client.ResidentialAddress.StreetNumber); Console.WriteLine("client residential StreetName: "+ client.ResidentialAddress.StreetName); Console.WriteLine("client delivery StreetNumber: "+ client.DeliveryAddress.StreetNumber); Console.WriteLine("client delivery StreetName: "+ client.DeliveryAddress.StreetName); } }
Even if all the properties of the complex type is nullable, the entire complex type objects cannot be set to NULL.
5. many-to-many relationship
publicclass Order { public int OrderID { get; set; } [Required] [StringLength(32, MinimumLength =2)] public string OrderTitle { get; set; } [Required] [StringLength(64, MinimumLength=5)] public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } public byte[] TimeStamp { get; set; } public virtual List<OrderDetail> OrderDetails { get; set; } public virtual List<Employee> InvolvedEmployees { get; set; } } publicclass Employee { public int EmployeeID { get; set; } public string EmployeeName { get; set; } public virtual List<Order> Orders { get; set; } }
modelBuilder.Entity<Employee>() .HasMany(e => e.Orders) .WithMany(e => e.InvolvedEmployees) .Map(m => { m.ToTable("EmployeeOrder"); m.MapLeftKey("EmployeeID"); m.MapRightKey("OrderID"); });
privatestaticvoid ManyToMany() { using (var context =new MyDomainContext()) { var order =new Order { OrderTitle ="Pens", CustomerName ="Mcdo’s", TransactionDate = DateTime.Now, InvolvedEmployees =new List<Employee>() }; var employee1 =new Employee { EmployeeName ="Joe", Orders =new List<Order>() }; var employee2 =new Employee { EmployeeName ="Black", Orders =new List<Order>() }; context.Orders.Add(order); order.InvolvedEmployees.Add(employee1); order.InvolvedEmployees.Add(employee2); context.SaveChanges(); }
6. Optimistic Concurrency
public class Order { public int OrderID { get; set; } [Required] [StringLength(32, MinimumLength = 2)] public string OrderTitle { get; set; } [Required] [StringLength(64, MinimumLength=5)] public string CustomerName { get; set; } public DateTime TransactionDate { get; set; } [ConcurrencyCheck] [Timestamp] public byte[] TimeStamp { get; set; } public virtual List<OrderDetail> OrderDetails { get; set; } public virtual List<Employee> InvolvedEmployees { get; set; } }
private static void ConcurrencyCheck() { Order originalOrder; // Create an order using (var context1 = new MyDomainContext()) { originalOrder = new Order { OrderTitle = "Paper", CustomerName = "*Bob*", TransactionDate = DateTime.Now }; context1.Orders.Add(originalOrder); context1.SaveChanges(); } // Simulate the modification of the created order by user X using (var context2 = new MyDomainContext()) { // Recreate the order object in order to attach it var order = new Order { OrderID = originalOrder.OrderID, OrderTitle = originalOrder.OrderTitle, CustomerName = originalOrder.CustomerName, TransactionDate = originalOrder.TransactionDate, TimeStamp = originalOrder.TimeStamp }; context2.Orders.Attach(order); // Alter the order order.CustomerName = "Robert"; context2.SaveChanges(); } // Simulate the modification of the created order by user Y (after user X already modified it) using (var context3 = new MyDomainContext()) { // Recreate the order in order to attach it var order = new Order { OrderID = originalOrder.OrderID, OrderTitle = originalOrder.OrderTitle, CustomerName = originalOrder.CustomerName, TransactionDate = originalOrder.TransactionDate, TimeStamp = originalOrder.TimeStamp }; context3.Orders.Attach(order); // Alter the order order.CustomerName = "Luke**"; try { context3.SaveChanges(); } catch (DbUpdateConcurrencyException ex) { Console.WriteLine("Concurrency exception on " + ex.Entries.First().Entity.GetType().Name); } } }
You can also force the EF believe that the order has been modified
context3.Entry(order).State = EntityState.Modified;
7.Inheritance