我最近在一个MVC项目中开始使用Entity Framework,我正在做的是掌握这些技术并且我有几个问题:..
我的第一个就是这个,这是我为实体保存的代码 - 这是最好的方式..它对我来说有点怀疑......
public bool SavePrank(PrankDefinition prank)
{
if (prank == null)
throw new ArgumentNullException("prank");
if (prank.ID == 0)
{
DataBase.Pranks.Add(prank);
DataBase.SaveChanges();
}
else
{
DataBase.Pranks.Attach(prank);
DataBase.Entry(prank).State = EntityState.Modified;
DataBase.SaveChanges();
}
return true;
}
我也得到了这个代码来获取最新版本的实体..
public List<PrankDefinition> GetPranks()
{
List<PrankDefinition> pranks = DataBase.Pranks.Where(p => p != null).ToList();
foreach (PrankDefinition prankDef in pranks)
{
DataBase.Entry(prankDef).Reload();
}
return pranks;
}
我必须在实体上调用.reload的原因是因为当另一个客户端正在使用该项目时 - 实体的更改不会立即反映(这很关键)。我的问题是 - 有更好的方法吗?我可以附加到Where方法以获取最新版本吗?
我的背景 - 如果有帮助..
public static DataContext DataBase
{
get
{
if (HttpContext.Current != null && HttpContext.Current.Session["DataBase"]== null)
{
HttpContext.Current.Session["DataBase"] = new DataContext();
}
return HttpContext.Current.Session["DataBase"] as DataContext;
}
set
{
if (HttpContext.Current != null)
HttpContext.Current.Session["DataBase"] = value;
}
}
任何帮助都会很棒!
编辑:更新到数据上下文
这会更好地实现DataContext吗?
public static DataContext DataBase
{
get { return new DataContext(); }
}
欢呼声。 STE。
答案 0 :(得分:4)
只是一些评论:
在我看来,SaveChanges
完成了一个工作单元,不属于像SavePrank
这样的单一存储库方法。我可能更喜欢这样的模式:
InsertOrUpdatePrank(prank); // = SavePrank without SaveChanges
ModifyPerhapsSomeOtherEntity(otherEntity);
SetPerhapsRelationshipBetweenPrankAndOtherEntity(prank, otherEntity);
// ... more ...
DataBase.SaveChanges();
这样,所有更改都会在一次交易中写入数据库。
你在哪里处理你的背景?如果将其实例化并将其存储在会话中但不明确地在代码中处理上下文,则上下文将存在于多个请求中。这是一个很大的麻烦的潜在来源,因为当您处理新请求时,您的上下文可能仍包含来自旧请求的实体。例如:如果带有prank
= 123的ID
在来自同一用户的两个后续请求中被更新两次(在同一会话中)DataBase.Pranks.Attach(prank)
将引发异常,因为在旧的恶作剧中以前具有相同ID的请求已附加到上下文中。在Web应用程序中,上下文的寿命永远不会超过单个请求,以避免此类问题以及更多问题。
如果按请求处理上下文,我认为不再需要“重新加载”实体。您无论如何都必须从数据库加载实体,因为每个上下文都是新的,当您输入操作时它是空的。所以,没有什么可以重装的。无论如何,当您运行查询时,您将从数据库中获取最新版本的entites。
Where(p => p != null)
毫无意义。要获取所有行,您只需编写:
List<PrankDefinition> pranks = DataBase.Pranks.ToList();