LINQ to SQL / Entity Framework 常用代码

创建时间:
2014-03-01 11:32
最近更新:
2018-10-05 21:03

通过主键查找实体 - DbSet<TEntity>.Find()

Syntax: public virtual TEntity DbSet<TEntity>.Find(params object[] keyValues);

var staff0 = context.Staff.Find(3); // DbSet 的 Find 方法,如果用主键在上下文中查找不到实体,就会到数据库中查询。
var staff1 = context.Staff.Find(3); // 从当前上下文中返回相同的实例 (没有查询数据库)。
  • 相比之下,即使实体已被 ObjectContext 缓存,Where(), First(), FirstOrDefault() 仍会执行数据库查询,而 Find() 会先在缓存中查找。
  • 因为 Find() 会先在缓存中查找,因此已 Add()、未 SaveChanges() 的记录,将出现在 Find() 的结果中。
  • Find() 可接收多个参数以对应 联合主键/复合主键/组合主键,注意:表示 联合主键/复合主键/组合主键 的参数的次序必须与该实体类中各主键声明的次序一致。

通过主键和外键查找实体

var lady = context.LadiesInWaiting.Find(3, "The EF Castle");

子查询

有网友用

var query= tb1.Where(n => tb2
	.Where(v => v.xx == "")
	.Select(v => v.Id)
	.Contains(n => n.Id)
);

实现

SELECT item FROM Tb1 WHERE Tb1.Id in
(SELECT Id FROM Tb2 where Tb2.xx="")

Tony 尚未验证。

使用.FirstOrDefault()查找单列

测试代码:

IQueryable<int> v =
	from e in db.Staffs
	where
		e.NameBack == nameBack &&
		e.Pw == pwBytes
	select e.Id;
int staffId = v.FirstOrDefault();//如无对应记录则返回 0。

EF 生成的 SQL:

exec sp_executesql
N'SELECT TOP (1) [Extent1].[Id] AS [Id] FROM [dbo].[Staff] AS [Extent1] WHERE ([Extent1].[NameBack] = @p__linq__0) AND ([Extent1].[Pw] = @p__linq__1)',
N'@p__linq__0 nvarchar(4000),@p__linq__1 varbinary(8000)',
@p__linq__0=N'asdf',
@p__linq__1=0x000000000000000000000000000000

Insert

var staff = new Staff{
	Name = "Tony",
	RoleOfStaffId = 0
};
context.Staff.Add(staff); // 添加到上下文中,尚未与数据库交易。
//context.Entry(staff).State = EntityState.Added; // 另一种插入方式。
context.SaveChanges(); // 插入数据库中,此时才与数据库交易。

注意:
插入之后,EF 会自动返回 scope_identity() 并自动将其赋给该实体的 ID 列。
但是,EF 认为所有的 ID 列都是自增标识列,解决方案:
方案 1,在 DbContext 派生类中添加以下代码:

protected override void OnModelCreating(DbModelBuilder modelBuilder){
	modelBuilder.Entity<PostBody>().Property(p => p.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
}

方案 2,在实体类的属性上添加特性:

public class BlogPost{
	[DatabaseGenerated(DatabaseGeneratedOption.None)]
	public int ID { get; set; }
}

以上注意复制自 http://blog.csdn.net/educast/article/details/8632806

在当前实体的关联实体中添加新的对象

// Add a new princess by setting a reference from a tracked unicorn
var unicorn = context.Unicorns.Find(1);
unicorn.Princess = new Princess { Name = "Belle" };

// Add a new unicorn by adding to the collection of a tracked princess
var princess = context.Princesses.Find(2);
princess.Unicorns.Add(new Unicorn { Name = "Franky" });

context.SaveChanges();

DbContext 中的 T-SQL 查询

1) SQL 语句查询实体 DbSet<T>.SqlQuery()

var unicorns = context.Unicorns.SqlQuery("select * from Unicorns").ToList();

2) SQL 语句查询非实体类型 DbContext.Database.SqlQuery<T>()

var unicornNames = context.Database.SqlQuery<string>("select Name from Unicorns").ToList();
var BlogMasters = context.Database.SqlQuery<BlogMaster>("select *from BlogMaster").ToList();

3) 执行 SQL 命令 DbContext.Database.ExecuteSqlCommand()

context.Database.ExecuteSqlCommand("update Unicorns set Name = 'Franky' where Name = 'Beepy'");

更新指定列

Tony copy from dudu:
http://www.cnblogs.com/dudu/archive/2011/04/06/entity_framework_set_modified_property.html
http://www.cnblogs.com/dudu/archive/2011/04/02/2003923.html
http://www.cnblogs.com/dudu/archive/2011/04/03/2004407.html

public void UpdateBlogCoinfigLastUpdatedTest()
{
	using (BlogDbContext context = new BlogDbContext()){
		var blog = new Blog(){
			BlogID = 0,
			LastModified = DateTime.Now
		};
		context.BlogConfigs.Attach(blog);
		var stateEntry = ((IObjectContextAdapter)context)
			.ObjectContext
			.ObjectStateManager
			.GetObjectStateEntry(blog);
		stateEntry.SetModifiedProperty("LastUpdated");
		context.SaveChanges();
	}
}

EF 生成的 SQL:

exec sp_executesql
N'update [dbo].[blog_Config] set [LastUpdated] = @0 where ([BlogID] = @1)',
N'@0 datetime2(7),@1 int',
@0='2011-04-06 14:12:28.2129938',
@1=0

Trim(), ToUpper(), Contains()

if(!string.IsNullOrWhiteSpace(filter.UnitName)) {
    query = query.Where(e =>
        e.UNIT_NAME.Trim().ToUpper().Contains(
            filter.UnitName.Trim().ToUpper()
        )
    );
}