EF Code First 入门
1、安装 Entity Framework
在 VS 编辑中点击 Tools -> Library Package Manager -> Package Manager Console
在 Package Manager Console 窗口中执行下面语句,安装最新版 Entity Framework:
PM> Install-Package EntityFramework
安装完成之后,将自动添加对 EntityFramework 的引用,并自动添加 App.config 和 packages.config 文件。
2、简单配置
在生成的配置文件中,加入如下代码,修改数据库连接信息:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<add name="EFTestContext" connectionString="Data Source=127.0.0.1;Database=EFTest;User=sa;Pwd=sapassword;" providerName="System.Data.SqlClient"/>
</connectionStrings>
3、实体类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
public string CategoryId { set; get; }
public string Name { set; get; }
public virtual ICollection<Product> Products { set; get; }
}
public class Product
{
public int ProductId { set; get; }
public string Name { set; get; }
public string CategoryId { set; get; }
public virtual Category Category { set; get; }
4、数据库 Context
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
namespace EFTest
{
public class EFTestContext : DbContext
{
public EFTestContext()
: base("EFTestContext") // 配置文件中连接字符串 Key 值
{
}
public DbSet<Category> Categories { set; get; }
public DbSet<Product> Products { set; get; }
}
5、读写数据
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
//新增 Category
using (var db = new EFTestContext())
{
var food = new Category
{
CategoryId = "A002",
Name = "文具"
};
db.Categories.Add(food);
int recordsAffected = db.SaveChanges();
}
using (var db = new EFTestContext())
{
//查询 Category
var category = db.Categories.Find("A003");
if (category == null)
{
category = new Category { CategoryId="A003", Name="体育" };
db.Categories.Add(category);
}
//新增 Product
var product = new Product { Name="篮球", Category=category };
db.Products.Add(product);
int recordsAffected = db.SaveChanges();
//使用LINQ查询 Product
var allProduct = from p in db.Products
where p.CategoryId == "A003"
orderby p.Name
select p;
foreach (var item in allProduct)
{
Console.WriteLine(item.Name);
}
}
Console.ReadKey();
6、数据初始化或实体类改变
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
/// <summary>
/// 执行对数据库的初始化操作。
/// </summary>
public static void Initialize()
{
using (EFTestContext db = new EFTestContext())
{
if (db.Database.Exists())
{
db.Database.Delete();
}
db.Database.Create();
//数据初始化操作
}
}
7、数据注释 Annotations
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.ComponentModel.DataAnnotations;
namespace EFTest.EFCodeFirst
{
public class Supplier
{
[Key]
public string SupplierCode { get; set; }
public string Name { get; set; }
}
EF 所支持的 Annotations 如下:
KeyAttribute
StringLengthAttribute
MaxLengthAttribute
ConcurrencyCheckAttribute
RequiredAttribute
TimestampAttribute
ComplexTypeAttribute
ColumnAttribute : Placed on a property to specify the column name, ordinal & data type
TableAttribute : Placed on a class to specify the table name and schema
InversePropertyAttribute : Placed on a navigation property to specify the property that represents the other end of a relationship
ForeignKeyAttribute : Placed on a navigation property to specify the property that represents the foreign key of the relationship
DatabaseGeneratedAttribute : Placed on a property to specify how the database generates a value for the property (Identity, Computed or None)
NotMappedAttribute : Placed on a property or class to exclude it from the database
8、Fluent API
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Infrastructure;
namespace EFTest
{
public class EFTestContext : DbContext
{
public EFTestContext()
: base("EFTestContext") // 配置文件中连接字符串 Key 值,不写默认为类名(EFTestContext)
{
}
public DbSet<Category> Categories { set; get; }
public DbSet<Product> Products { set; get; }
public DbSet<Supplier> Suppliers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//移除复数表名的契约
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
//防止黑幕交易 要不然每次都要访问 EdmMetadata这个表
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<Supplier>()
.Property(s => s.Name)
.IsRequired();
}
}
9、附加
操作存储过程或SQL语句:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
{
using (var db = new EFTestContext())
{
//执行存储过程(含有参数,如无参数,去掉最后的参数)
int recordsAffected = db.Database.ExecuteSqlCommand("sp_DeleteProductById @id", new SqlParameter("@id", 1));
//执行SQL语句
string sql = string.Format("INSERT INTO [dbo].[Product] VALUES ('测试','A003')");
recordsAffected = db.Database.ExecuteSqlCommand(sql);
}
注解:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System.ComponentModel.DataAnnotations.Schema;
namespace EFTest
{
//自定义表名
[Table("MyPerson")]
public class Person
{
//主键,默认情况下属性被命名为ID、id或者[ClassName]Id
[Key]
public int Id { set; get; }
//设置字段不能为空
[Required]
public string Name { set; get; }
//设置字段的长度范围
[MaxLength(20),MinLength(5)]
public string ClassName { set; get; }
//不会创建的数据表字段
[NotMapped]
public int MyProperty { set; get; }
[Column("PersonPhoto",TypeName="image")]
public byte[] Image { set; get; }
}
谢谢。。。