实体框架 - 建议和最佳实践
我最近开始在一个 MVC 项目上使用实体框架,我正在做这个项目来掌握这些技术,我有几个问题:..
我的第一个问题是这个,这是我的保存代码实体 - 这是最好的方法吗..对我来说有点可疑..
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(); }
}
干杯。 圣。
I've recently started with Entity Framework on an MVC project I'm doing to get the grips with the technologies and I've got a few questions : ..
My first one is this, this is my Save code for an entity - Is this the best way.. it looks a little suspect to me..
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;
}
Ive also got this code for getting the latest version of the entitys..
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;
}
the reason ive had to call .reload on the entity's is because when another client is using the project - there changes to entity's are not reflected instantly (which is critical). My question for this - is there a better way to do this? is there something I can attach to the Where method to get the latest versions?
my context - if it helps..
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;
}
}
any help would be fantastic!
EDIT : UPDATE TO DATA CONTEXT
Would this be a better implementation of the DataContext?
public static DataContext DataBase
{
get { return new DataContext(); }
}
cheers.
ste.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只是几点说明:
在我看来,
SaveChanges
完成了一个工作单元,不属于像SavePrank
这样的单一存储库方法。我可能更喜欢这样的模式:这样,所有更改都会在单个事务中写入数据库。
你在哪里处理你的上下文?如果您实例化并将其存储在会话中,但没有在代码中显式处置上下文,则上下文将存在于多个请求中。这是一个潜在的大麻烦来源,因为当您处理新请求时,您的上下文可能仍然包含来自旧请求的实体。例如:如果
ID
= 123 的恶作剧
在同一用户(在同一会话中)的两个后续请求中更新两次DataBase.Pranks.Attach( prank)
会抛出异常,因为来自具有相同 ID 的先前请求的旧恶作剧已经附加到上下文。在 Web 应用程序中,上下文的生存时间不应长于单个请求,以避免此类问题及更多问题。如果您根据请求处理上下文,我认为不再需要“重新加载”实体。无论如何,您都必须从数据库加载实体,因为当您输入操作时,每个上下文都是新的并且是空的。所以,没有什么可以重新加载的。无论如何,当您运行查询时,您都会从数据库中获取最新版本的实体。
Where(p => p != null)
没有任何意义。要获取所有行,您只需编写:Just a few remarks:
In my opinion
SaveChanges
finishes a unit of work and doesn't belong to single repository methods likeSavePrank
. I would probably prefer a pattern like this:This way all changes are written to the database in a single transaction.
Where do you dispose your context? If you instantiate and store it in a session but don't dispose the context in your code explicitely the context lives across multiple requests. This is a potential source of big trouble because your context might still contain entities from older requests when you process a new request. For example: If the
prank
withID
= 123 gets updated twice in two subsequent requests from the same user (in the same session)DataBase.Pranks.Attach(prank)
would throw an exception because on old prank from a former requests with same ID is already attached to the context. In a web application a context should never live longer than a single request to avoid problems like this and many more.If you dispose the context per request I don't see the need anymore to "reload" entities. You have to load the entities from the database anyway because each context is a new one and empty when you enter an action. So, there is nothing to reload. You'll get the latest version of your entites from the database anyway when you run your queries.
Where(p => p != null)
makes no sense. To fetch all rows you can just write: