I.EF default mapping
project we created in the previous section, by defining entity class can automatically generate a database, and EF help us to automatically set up a database primary keys, foreign keys and table names and field type, etc., this is the default mapping of EF. divided into specific:
- database mapping: Code First by default database on the local SQL Expression and DbContext to create a subclass of the same database as the full name, full name refers to a namespace plus class name. Of course, in front of us in the configuration file specifies the database to connect to;
- table mapping: Code First will follow the type name of the default build complex data tables, such as Destination class corresponding table name is called Destinations;
- column mapping: Code First default will follow the class attribute names created column, it also has the default data type mapping habits, int is mapped to interger, string is mapped to nvarchar (max), decimal is mapped to decimal ( 18,2);
- primary key mapping: Code First default properties of the class will need to find a name for the Id or type name + Id attribute of type int as the primary key and is auto-increment fields.
extracted from the here
default mapping generally only simple mapping, of course, these can be modified, please read on.
II. Using Data Annotations and the Fluent API configuration database mapping
Data Annotations translation is data annotation, through the properties directly in the entity class labels on things like filling up the database mapping; < br /> Fluent API translation is fluent API, Fluent API is defined in the database configuration DbContext way. To use the Fluent API must in your custom class that inherits from DbContext overloaded OnModelCreating this method.
Note: Using Data Annotations must add references: using System.ComponentModel.DataAnnotations;
more specific references refer to the source end of this chapter
combat: < br /> 1.Data Annotations:
Set Destination Table Name is not null :
[Required]
public string Name { get; set; }
very simple, direct on the property plus [Required] annotation to;
2.Fluent API:
with Fluent api must override OnModelCreating methods, we re-write in the context class OnModelCreating method does not add an empty configuration:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<CodeFirst.Model.Destination>().Property(d => d.Name).IsRequired();
}
Note: I have modified the default class library namespace are added a CodeFirst. easy to distinguish, other libraries to call, I also used to use the full namespace library again. entity class to call.
above method means: first find the need to configure entity classes, and then point out the property Property that is, => is a lambda expression wording, find the Name property, and then call IsRequired method is not set to null. First saw this thing certainly is not well understood. Right, the wording is very fixed, write more on the familiar.
EF can be configured in two ways mapped to the database. I prefer the Fluent API way, so the release of the demo Data Annotations are some exceptions, but are commented out. With the development of in-depth, some things still need to use the Fluent API to configure the way out.
thinking:
using Fluent API mode configuration, each method requires OnModelCreating write the previous line configuration, such an entity class if there are three attributes need to be configured, 10 entity class will need to configure the 30, then you have to write in a way OnModelCreating line 30, cumbersome and difficult to maintain.
Solution:
Note that the return value can be seen out modelBuilder the Entity <> generic method's return value is EntityTypeConfiguration <> generic class. We can define a class that inherits from EntityTypeConfiguration <> generic class to define the domain of the class for each class in the database configuration.
ok, we create a new class library in DataAccess inherited from EntityTypeConfiguration <> generic class DestinationMap class, write in the constructor Configuration:
public class DestinationMap : EntityTypeConfiguration<CodeFirst.Model.Destination>
{
public DestinationMap()
{
Property(d => d.Name).IsRequired();
}
}
need to add references: using System.Data.Entity.ModelConfiguration;
so that later Destination come here need to be configured configuration, and then added to the context OnModelCreating method can be:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new DestinationMap());
}
configuration of other classes, too, first add a class name + Map method (named above), and then add to OnModelCreating method.
freely configure some properties, and then ran down the program to see the generated database:
Visible: Name can not be empty column is already, Description also set the length does not exceed 500 and so on.
Note: If you re-run the program to generate the database reported this error:
The model backing the 'BreakAwayContext' context has changed since the database was created. Either manually delete / update the database, or call Database.SetInitializer with an IDatabaseInitializer instance. For example, the DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate the database, and optionally seed it with new data.
mean is, the current database is in use, can not be removed and re-generation. Disconnects from the database at this time, pitted under the program on it. Each subsequent re-run entity class configuration procedures need to disconnect the database connection.
not know if you still remember the first article talking about EdmMetadata this table, EF will automatically help us generate this table . This table is to monitor changes in the entity class, in fact, is criticized, each operation to access the database will be sent to this table sql database using sql Profiler trace can be found under the following sql:
SELECT TOP (1)
[Extent1].[Id] AS [Id],
[Extent1].[ModelHash] AS [ModelHash]
FROM [dbo].[EdmMetadata] AS [Extent1]
ORDER BY [Extent1].[Id] DESC
added: sql Profiler is a sql statement sent to the database monitoring tool. sql server 2008 comes with simple operation, if not your own search for relevant information. Without this tool, it is a database or database installed the wrong version of a problem. sql Profiler tool behind this talk one to one, one to many, many to many various operations will often use to, but also our performance debugging EF statement is a good helper:
extended : We can OnModelCreating method to add:
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();//防止黑幕交易 要不然每次都要访问
also need to introduce a new namespace:
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Infrastructure;
first one is to remove the plural table names contract is EF default generated table name is the plural form of the entity class, there is this sentence, the table name is entity class name, not combined with a s, of course, you can also configure this powerful Fluent API.
second sentence is to remove access for EdmMetadata table, next to operate the database, there will be a visit EdmMetadata sql table .
Note: If you already have a database before, then remove the right EdmMetadata table plus access to rerun the configuration program reported a NotSupportedException fault:
Model compatibility cannot be checked because the EdmMetadata type was not included in the model. Ensure that IncludeMetadataConvention has been added to the DbModelBuilder conventions.
< span style = "font-size: 15px;"> This time, we first BreakAwayConfigFile database separation must then be locally deleted, rerun the program on it.
If you do not know sql server mdf and ldf files of the default path, your own search.
results ran under the program, does not produce right EdmMetadata table access sql, but sql Profiler to monitor more sql statement is sent to the database. Had access to at least one EdmMetadata table sql, much more the result sql, and if re-generate the database must also be manually detach the existing database and delete the database file on the hard disk. Here so do not use or to be negotiable, temporarily comment out:
/ / modelBuilder.Conventions.Remove
Thinking: EF team designed EdmMetadata table must have its reasons, to remove access to it is not necessarily science. This study demonstrates only do real projects may also rarely use Code First way to generate the database. At least version 4.1 using the EF Code First is flawed, each will get rid of all the data, this is definitely inappropriate. Subsequent versions of the data migration function to solve this, we're just learning the 4.1 version of this classic EF.
added: actual development or database First way more mainstream.
above only illustrates simple Data Annotations and the Fluent API some simple configuration, in fact there are many, some are listed below commonly, beginners should all try to knock, and then according to the generated database to learn how to configure:
//【主键】
//Data Annotations:
[Key]
public int DestinationId { get; set; }
//Fluent API:
public class BreakAwayContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Destination>().HasKey(d => d.DestinationId);
}
}
//【外键】
//Data Annotations:
public int DestinationId { get; set; }
[ForeignKey("DestinationId")]
public Destination Destination { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().HasRequired(p => p.Destination).WithMany(p=>p.Lodgings).HasForeignKey(p => p.DestinationId);
//【长度】
//Data Annotations:通过StringLength(长度),MinLength(最小长度),MaxLength(最大长度)来设置数据库中字段的长度
[MinLength(10),MaxLength(30)]
public string Name { get; set; }
[StringLength(30)]
public string Country { get; set; }
//Fluent API:没有设置最小长度这个方法
modelBuilder.Entity<Destination>().Property(p => p.Name).HasMaxLength(30);
modelBuilder.Entity<Destination>().Property(p => p.Country).HasMaxLength(30);
//【非空】
//Data Annotations:
[Required(ErrorMessage="请输入描述")]
public string Description { get; set; }
//Fluent API:
modelBuilder.Entity<Destination>().Property(p => p.Country).IsRequired();
//【数据类型】
Data Annotations:
将string映射成ntext,默认为nvarchar(max)
[Column(TypeName = "ntext")]
public string Owner { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.Owner).HasColumnType("ntext");
//【表名】
//Data Annotations:
[Table("MyLodging")]
public class Lodging
{
}
//Fluent API
modelBuilder.Entity<Lodging>().ToTable("MyLodging");
//【列名】
//Data Annotations:
[Column("MyName")]
public string Name { get; set; }
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.Name).HasColumnName("MyName");
//【自增长】
//Data Annotations
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] Guid类型的主键、自增长
public Guid SocialId { get; set; }
//Fluent API:
modelBuilder.Entity<Person>().Property(p => p.SocialId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
//【忽略列映射】
//Data Annotations:
[NotMapped]
public string Name
{
get
{
return FirstName + " " + LastName;
}
}
//Fluent API:
modelBuilder.Entity<Person>().Ignore(p => p.Name);
//【忽略表映射】
//Data Annotations:
[NotMapped]
public class Person
{ }
//Fluent API:
modelBuilder.Ignore<Person>();
//【时间戳】
//Data Annotations:Timestamp
[Timestamp]
public Byte[] TimeStamp { get; set; } 只能是byte类型
//Fluent API:
modelBuilder.Entity<Lodging>().Property(p => p.TimeStamp).IsRowVersion();
//【复杂类型】
//Data Annotations:
[ComplexType]
public class Address
{
public string Country { get; set; }
public string City { get; set; }
}
//Fluent API:
modelBuilder.ComplexType<Address>();
derived partly from here
now looked likely to head, only to do to understand and to facilitate post-inspection. Follow speaking one to one, one to many and many to many relationship repeatedly when handwriting Fluent API will be very good to understand.
Source: Download
Series of articles Navigation:
- EF Code First First Experience
- EF's default mapping and how to use Data Annotations and the Fluent API configuration database mapping
- there are a lot to be continued ....
没有评论:
发表评论