Entity Framework学习三:查询、插入、更新和删除操作

1.LINQ过滤数据 

var query = from person in context.People
                        where person.FirstName.StartsWith("a")
                        select person;
var methodQuery = context.People.Where(p => p.FirstName.StartsWith("a"));

两种不同的写法,效果一样。

  • 多条件组合查找
var query = from person in context.People
                        where person.FirstName.StartsWith("a") &&
                        person.LastName.EndsWith("b")
                        select person;
var methodQuery = context.People.Where(p => p.FirstName.StartsWith("a") && p.LastName.EndsWith("b"));
  • 对查找结果排序升序:
            var query = from person in context.People
                        where person.FirstName.StartsWith("a") &&
                        person.LastName.EndsWith("b")
                        orderby person.FirstName,person.LastName
                        select person;
            var methodQuery = context.People
                .Where(p => p.FirstName.StartsWith("a") && p.LastName.EndsWith("b"))
                .OrderBy(p => p.FirstName)
                .ThenBy(p => p.LastName);
  • 对查找结果排序降序:
            var query = from person in context.People
                        where person.FirstName.StartsWith("a") &&
                        person.LastName.EndsWith("b")
                        orderby person.FirstName,person.LastName
                        descending
                        select person;
            var methodQuery = context.People
                .Where(p => p.FirstName.StartsWith("a") && p.LastName.EndsWith("b"))
                .OrderByDescending(p => p.FirstName)
                .ThenByDescending(p => p.LastName);
  • 延迟加载和贪婪加载(Lazy Loading和eager loading)

如果不确定是否要加载关联数据时就使用延迟加载,否则就使用贪婪加载。当然这个不是固定的看具体什么场景下使用。默认情况下延迟加载是生效的,可以在创建DbContex后配置选项

context.Configuration.LazyLoadingEnabled = false;

2.插入数据

多种方法,不多说看代码:

  • 方法一
var person = new Person
{
BirthDate = new DateTime(1980, 1, 2),
FirstName = "John",
HeightInFeet = 6.1M,
IsActive = true,
LastName = "Doe",
MiddleName = "M"
};
person.Phones.Add(new Phone { PhoneNumber = "1-222-333-4444" });
person.Phones.Add(new Phone { PhoneNumber = "1-333-4444-5555" });
using (var context = new Context())
{
context.People.Add(person);
context.SaveChanges();
}

方法二:改变Entity的状态

using (var context = new Context())
{
context.Entry(person2).State = EntityState.Added;
context.SaveChanges();
}

EntityState:Added、Deleted、Detached(DbContex不追踪Entity状态)、Modified、Unchanged

3.更新数据

多种方法:

方法一:

using (var context = new Context())
{
var person = context.People.Find(1);
person.FirstName = "New Name";
context.SaveChanges();
}

方法二(建议使用)注意标记部分:

var person2 = new Person
{
PersonId = 1,
BirthDate = new DateTime(1980, 1, 2),
FirstName = "Jonathan",
HeightInFeet = 6.1m,
IsActive = true,
LastName = "Smith",
MiddleName = "M"
};
person2.Phones.Add(new Phone
{
PhoneNumber = "updated 1",
PhoneId = 1,
PersonId = 1
});
person2.Phones.Add(new Phone
{
PhoneNumber = "updated 2",
PhoneId = 2,
PersonId = 1
});
using (var context = new Context())
{
context.Entry(person2).State = EntityState.Modified;
context.SaveChanges();
}

你会发现执行上面代码只有Person数据更新了,Phone数据没有更新,这是因为Insert和Update机制不一样,Update时设置了Entity的EntityState,但是并没有传播到子数据的状态,需要都上面程序做些修改

using (var context = new Context())
{
context.Entry(person2).State = EntityState.Modified;
foreach (var phone in person2.Phones)
{
context.Entry(phone).State = EntityState.Modified;
}
context.SaveChanges();
}

在开发Web程序时可以使用AsNoTracking来提高查询性能

using (var context = new Context())
{
var query = context.People.Include(p =>
p.Phones).AsNoTracking();
foreach (var person in query)
{
foreach (var phone in person.Phones)
{
}
}
}
  • 使用Attach 会改变状态为Unchanged,并开始追踪Entity的状态
var person3 = new Person
{
PersonId = 1,
BirthDate = new DateTime(1980, 1, 2),
FirstName = "Jonathan",
HeightInFeet = 6.1m,
IsActive = true,
LastName = "Smith",
MiddleName = "M"
};
using (var context = new Context())
{
context.People.Attach(person3);
person3.LastName = "Updated";
context.SaveChanges();
}

上面代码执行将仅仅只会更新LastName列。也可以用以下代码替代Attach方法

context.Entry(person3).State = EntityState.Unchanged

4.删除数据

  • 方法一:先查询出数据,再删除(注意删除子数据可以使用设置数据库级联删除更方便)
using (var context = new Context())
{
var toDelete = context.People.Find(personId);
toDelete.Phones.ToList().ForEach(phone =>
    context.Phones.Remove(phone));
context.People.Remove(toDelete);
context.SaveChanges();
}
  • 方法二:使用改变状态
var toDeleteByState = new Person { PersonId = personId };
toDeleteByState.Phones.Add(new Phone
{
PhoneId = phoneId1,
PersonId = personId
});
toDeleteByState.Phones.Add(new Phone
{
PhoneId = phoneId2,
PersonId = personId
});
using (var context = new Context())
{
   context.People.Attach(toDeleteByState);
   foreach (var phone in toDeleteByState.Phones.ToList())
   {
      context.Entry(phone).State = EntityState.Deleted;
   }
   context.Entry(toDeleteByState).State = EntityState.Deleted;
   context.SaveChanges();
}

5.查询本地数据

当需要查询的数据已经在内存中,而未提交到数据库时对内存数据进行查询

var localQuery = context.People.Local.Where(p =>
p.LastName.Contains("o")).ToList();
posted @ 2015-09-20 17:52  古韵古风  阅读(370)  评论(0编辑  收藏  举报