实体框架学习

1.当你完成对对象的操作之后,实体框架应用 change tracker 去保持对你所做的跟踪。
As you perform operations on your object instances, Entity Framework uses its change
tracker to keep track of what you have done.
2.增加
 eg:
 private static void AddMachuPicchu()
{
using (var context = new BreakAwayContext())
{
var machuPicchu = new Destination
{
Name = "Machu Picchu",
Country = "Peru"
};
context.Destinations.Add(machuPicchu);
context.SaveChanges();
}
}
3.修改
private static void ChangeGrandCanyon()
{
using (var context = new BreakAwayContext())
{
var canyon = (from d in context.Destinations
where d.Name == "Grand Canyon"
select d).Single();
canyon.Description = "227 mile long canyon.";
context.SaveChanges();
}
}
4.删除
private static void DeleteWineGlassBay()
{
using (var context = new BreakAwayContext())
{
var bay = (from d in context.Destinations
where d.Name == "Wine Glass Bay"
select d).Single();
context.Destinations.Remove(bay);
context.SaveChanges();
}
}
注意:当调用Remove在DbSet上时将会设置实体为删除状态,但调用 一个集合的导航属性 不会删除对应的的实体 删除的仅仅是关系,而不是实体本身。
While calling Remove on a DbSet will mark an entity for deletion, calling Remove on a
collection navigation property will not. Removing an entity from a collection navigation
property will mark the relationship between the two entities as deleted but not the
entities themselves.

不用从数据库中加载数据也能删除的方法
方法1:
通过DbSet.Attach方法将构建的对象附加,然后调用Remove方法告诉实体框架要删除这个数据
var toDelete = new Destination { DestinationId = 2 };
context.Destinations.Attach(toDelete);
context.Destinations.Remove(toDelete);
context.SaveChanges();

方法2: 直接通过Sql语句
Another way to delete entities without loading them is to use DbContext.Database.Exe
cuteSqlCommand to execute some raw SQL to perform the deletion in the database.
eg:
context.Database.ExecuteSqlCommand(
"DELETE FROM baga.Locations WHERE LocationName = 'Hawaii'");
方法3:通过设置状态来删除
private static void DeleteDestination(Destination destination)
{
using (var context = new BreakAwayContext())
{
context.Entry(destination).State = EntityState.Deleted;
context.SaveChanges();
}
}
方法4:通过编号来删除
private static void DeleteDestination(int destinationId)
{
using (var context = new BreakAwayContext())
{
var destination = new Destination { DestinationId = destinationId };
context.Entry(destination).State = EntityState.Deleted;
context.SaveChanges();
}
}
注意删除时进行冲突检测:
需要将tocken值和id值同步设置
If your entity contains any concurrency tokens, these properties are also
used to construct the DELETE statement. You can still use the stub entity
approach, but you will need to set values for the concurrency token
properties as well.

因为我们可以使用原生态的SQL,我们可绕过任何映射通过使用实体框架。
Because we are using raw SQL, we are bypassing any mapping that is done using Entity
Framework.

删除关联:必须要把相关联的记录加载出来
//这个方法描述的关系时弱关联的关系即:外键可空
private static void DeleteTrip()
{
using (var context = new BreakAwayContext())
{
var trip = (from t in context.Trips
where t.Description == "Trip from the database"
select t).Single();

var res = (from r in context.Reservations
where r.Trip.Description == "Trip from the database"
select r).Single();

context.Trips.Remove(trip);
context.SaveChanges();
}
}

级联删除:删除父表的时候同时删除所有的子表信息,这需要在数据库中配置
private static void DeleteGrandCanyon()
{
 using (var context = new BreakAwayContext())
 {
  var canyon = (from d in context.Destinations
   where d.Name == "Grand Canyon"
   select d).Single();
  context.Destinations.Remove(canyon);
  context.SaveChanges();
 }
}
无级联删除:需要手工的将子表逐个删除或将子表的父表赋值为新的类
//直接删除子表:注意这里一定要使用ToList()方法做一个拷贝,不要直接访问canyon.Loadgings对象

foreach (var lodging in canyon.Lodgings.ToList())
{
 context.Lodgings.Remove(lodging);
}

//将子类替换对应的父类
foreach (var lodging in canyon.Lodgings.ToList())
{
 lodging.Destination = hawaii;
}

??的用法
var person = context.People.Find(ssn)
?? context.People.Add(new Person//如果??前的对象是空的那个就用后边的对象来代替
{
SocialSecurityNumber = ssn,
FirstName = "<enter first name>",
LastName = "<enter last name>"
});
----------------------------n层架构--------------------------------
The N-Tier pattern makes data access more complex because there is no longer a context
tracking changes that are made to each entity. The data is fetched using one context,
and returned to the client where there is no context to track changes. The data is then
sent back to the server and must be persisted back to the database using a new instance
of the context.
n层模式使得数据访问更加的复杂因为这不再是对每个实体的跟踪在一个context中。读取使用一个context返回到客户端之后无法再次跟踪改变。数据再次发回服务端而且必须持久化到数据库使用一个新的contex;
代码使用DbContext.Entry方法来访问实体状态的追踪信息。

如何解决N层架构,实体框架团队建议使用WCF Data Service 数据服务。
1.在服务端使用明确的方法Using Explicit Operations on the Server Side

For example, rather than the SaveDestinationAndLodgings method
we saw earlier in this chapter, you could expose AddDestination and UpdateDestina
tion methods.
预期使用保存DestinationAndLoading 像我们之前章节中的方法,我们拆分成 AddDestionation 和 updateDestina两个方法明确 指示

2.在服务器端替换更改。Replaying Changes on the Server
  Rather than serializing entities, you’ll use a temporary context to fetch any data from the database
and then manipulate the data to mimic client-side changes.
代替序列化实体的方法,你可以使用临时的上下文从数据库获取任何数据,然后调整数据来模仿客户端的调整。
*实体框架的针对对象的更改可以具体到某一个属性也就是某个列上,而不是更新所有的属性。
eg:exec sp_executesql N'UPDATE [dbo].[Person]
SET [P_Name] = @0
WHERE (([PK_Person] = @1) AND ([Version] = @2))
',N'@0 nvarchar(20),@1 int,@2 binary(8)',@0=N'李仲超466a9173-a',@1=1,@2=0x00000000000007D1 只是更新人员的名称
解释:During
SaveChanges an UPDATE statement will be sent to the database to apply the changes.
A list of the properties that have been modified is also kept to determine which
columns should be set in the UPDATE statement.
我们可以使用DbContext.Entry方法来获取对一个实体的改变追踪信息
we could use DbContext.Entry to get access to the change tracking information for an
entity.

我们使用 状态 属性读取 实体的追踪信息中的信息,我们也可以设置这个属性
We used the State property on the change tracking information to read the state
of an entity, but we can also set this property, too.
eg:通过改变实体状态追踪信息 来增加实体
private static void AddDestination(Destination destination)
{
using (var context = new BreakAwayContext())
{
context.Entry(destination).State = EntityState.Added;
context.SaveChanges();
}
}

离线修改关联关系
private static void TestUpdateLodging()
{
int reefId;
Lodging davesDump;
using (var context = new BreakAwayContext())
{
reefId = (from d in context.Destinations
where d.Name == "Great Barrier Reef"
select d.DestinationId).Single();
davesDump = (from l in context.Lodgings
where l.Name == "Dave's Dump"
select l).Single();
}
davesDump.DestinationId = reefId;
UpdateLodging(davesDump);
}
private static void UpdateLodging(Lodging lodging)
 {
 using (var context = new BreakAwayContext())
{
context.Entry(lodging).State = EntityState.Modified;
context.SaveChanges();
}
}

N层架构下的修改
//获取数据
  private void button6_Click(object sender, EventArgs e)
        {
            Person p = null;
            using (PersonContext context = new PersonContext())
            {
                p =  context.Person.SingleOrDefault();
            }

            this.UpdatePerson(p);
        }
  //对数据修改之后进行提交
        private void UpdatePerson(Person p)
        {
            using (PersonContext context = new PersonContext())
            {
                p.PersonName = DateTime.Now.ToString("yyyyMMddHHmmss");
                context.Entry(p).State = EntityState.Modified;//模拟客户端的修改

    //注意对检测冲突致的处理
                context.Entry(p).Property(r => r.Version).OriginalValue = p.Version;
                context.Entry(p).Property(r => r.Version).IsModified = false;
                context.SaveChanges();
            }
        }

posted @ 2013-10-31 19:20  feidaochuanqing  阅读(444)  评论(0编辑  收藏  举报