[英]Unexpected behavior in entity framework
我遇到了我認為實體框架非常奇怪的情況。 基本上,如果我使用sql命令直接更新行,當我通過linq檢索該行時,它沒有更新的信息。 有關更多信息,請參閱以下示例。
首先,我創建了一個簡單的DB表
CREATE TABLE dbo.Foo (
Id int NOT NULL PRIMARY KEY IDENTITY(1,1),
Name varchar(50) NULL
)
然后我創建了一個控制台應用程序,用於向DB添加對象,使用sql命令更新它,然后檢索剛剛創建的對象。 這里是:
public class FooContext : DbContext
{
public FooContext() : base("FooConnectionString")
{
}
public IDbSet<Foo> Foo { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Foo>().ToTable("Foo");
base.OnModelCreating(modelBuilder);
}
}
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
}
public class Program
{
static void Main(string[] args)
{
//setup the context
var context = new FooContext();
//add the row
var foo = new Foo()
{
Name = "Before"
};
context.Foo.Add(foo);
context.SaveChanges();
//update the name
context.Database.ExecuteSqlCommand("UPDATE Foo Set Name = 'After' WHERE Id = " + foo.Id);
//get the new foo
var newFoo = context.Foo.FirstOrDefault(x => x.Id == foo.Id);
//I would expect the name to be 'After' but it is 'Before'
Console.WriteLine(string.Format("The new name is: {0}", newFoo.Name));
Console.ReadLine();
}
}
底部的寫行打印出“之前”,但我希望它打印出“之后”。 關於它的奇怪之處在於,如果我運行探查器,我會看到sql查詢運行,如果我自己在管理工作室中運行查詢,則返回“After”作為名稱。 我正在運行SQL Server 2014。
有人可以幫我理解這里發生了什么嗎?
更新:
它將轉到FirstOrDefault行的數據庫。 請參閱sql profiler附帶的屏幕截圖。
所以我的問題是這樣的:
1)如果是緩存,不應該不去DB嗎? 這是EF中的一個錯誤嗎?
2)如果要進入db並花費資源,不應該更新EF對象。
FooContext
包括更改跟蹤和緩存,因此從查詢返回的內存中對象與先前添加的實例相同。 調用SaveChanges()
確實清除了上下文,並且FooContext
不知道數據庫中它下面發生的更改。
這通常是一件好事 - 不會為每個操作進行昂貴的數據庫調用。
在您的示例中,嘗試從新的FooContext
進行相同的查詢,您應該看到“After”。
回答您的更新問題,是的,您是對的。 在你使用FirstOrDefault()
之前我錯過了。 如果您正在使用context.Find(foo.Id)
,正如我錯誤地假設的那樣,那么就沒有查詢。
至於為什么內存中的對象沒有更新以反映數據庫中的變化,我需要做一些研究來做更多的事情而不是推測。 那就是說,這是我的猜測:
SaveChanges()
會怎樣? - 會發生什么?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.