实体框架是提交模式吗?

发布于 2024-12-14 23:49:27 字数 2051 浏览 1 评论 0原文

我有许多方法最终会调用我的 this._context.SubmitChanges 方法。由于我的所有方法都是异步操作的,因此在我的应用程序中(尽管不太可能),多个方法可能会在另一个提交更改完成之前尝试提交。

现在,我知道我可以使用 IsSubmitting 方法来确保我不会在另一个提交发生时尝试调用一个提交。我只是想知道从这里该往哪个方向走。我不确定是否真的有必要设置一个队列,因为希望提交更改的多个实体都将在 .SubmitChanges 调用下汇总。

我所做的每个提交更改都有一个回调函数。一种选择是在我的应用程序中添加一个标志,在回调中检查该标志是否在过渡期间设置。如果设置了标志,则会发射另一轮。虽然看起来很黑客。有更好的办法吗?

谢谢。

[编辑]

我没有我想要的那么多 EF fu,但我认为我将它们分开,如下面的代码(我的 VM 构造函数)中所述...当我想要提交更改时,它位于每个独立的实体列表上...

这是对submitchanges的调用示例(其中每个调用都使用不同的实体列表)

this._keywordSource.Add(new Keyword() { keyword = searchText });
if (this._context.Keywords.HasChanges && !this._context.IsSubmitting)
{
    this._context.SubmitChanges(KeywordsAddedCompleted, null);
}

这是我的视图模型构造函数中的代码:

this._gnipRuleSource = new EntityList<GnipRule>(this._context.GnipRules);
this._keywordSource = new EntityList<Keyword>(this._context.Keywords);
this._cachedSource = new EntityList<CachedKeywordResult>(this._context.CachedKeywordResults);
this._feedSourceSource = new EntityList<FeedSource>(this._context.FeedSources);

this._gnipRuleLoader = new DomainCollectionViewLoader<GnipRule>(LoadGnipRules, LoadGnipRulesCompleted);
this._keywordLoader = new DomainCollectionViewLoader<Keyword>(LoadKeywords, LoadKeywordsCompleted);
this._cachedLoader = new DomainCollectionViewLoader<CachedKeywordResult>(LoadCachedKeywords, LoadCachedKeywordsCompleted);
this._feedSourceLoader = new DomainCollectionViewLoader<FeedSource>(LoadFeedSources, LoadFeedSourcesCompleted);

this._gnipRuleView = new DomainCollectionView<GnipRule>(this._gnipRuleLoader, this._gnipRuleSource);
this._keywordView = new DomainCollectionView<Keyword>(this._keywordLoader, this._keywordSource);
this._cachedView = new DomainCollectionView<CachedKeywordResult>(this._cachedLoader, this._cachedSource);
this._feedSourceView = new DomainCollectionView<FeedSource>(this._feedSourceLoader, this._feedSourceSource);

I have a number of methods that ultimately call my this._context.SubmitChanges method. Because all of my methods operate asynchronously, it's possible in my app (albiet unlikely) that multiple methods might try and submit before another submitchanges is complete.

Now, I know I can use the IsSubmitting method to make sure I don't try and call one submit while another is occurring. I'm just wondering which direction to go from here. I'm not sure it's really necessary to to set up a queue, since multiple entities looking to submit changes will all get rolled up under a .SubmitChanges call.

I have a callback function on each of the submitchanges that I make. One option would be to throw a flag into my app that, in the callback, checks to see if the flag was set during the interim. If flag was set, it fires off another round. Seems hackish though. Is there a better way?

Thanks.

[Edit]

I don't have as much EF fu as I'd want, but I think I'm keeping them separate, as outlined in the code below (my VM constructor)... when I'm looking to submit changes, it's on each of these independent entityLists...

Here is an example call to submitchanges (where each call is using a different entitylist)

this._keywordSource.Add(new Keyword() { keyword = searchText });
if (this._context.Keywords.HasChanges && !this._context.IsSubmitting)
{
    this._context.SubmitChanges(KeywordsAddedCompleted, null);
}

Here is code from my viewmodel constructor:

this._gnipRuleSource = new EntityList<GnipRule>(this._context.GnipRules);
this._keywordSource = new EntityList<Keyword>(this._context.Keywords);
this._cachedSource = new EntityList<CachedKeywordResult>(this._context.CachedKeywordResults);
this._feedSourceSource = new EntityList<FeedSource>(this._context.FeedSources);

this._gnipRuleLoader = new DomainCollectionViewLoader<GnipRule>(LoadGnipRules, LoadGnipRulesCompleted);
this._keywordLoader = new DomainCollectionViewLoader<Keyword>(LoadKeywords, LoadKeywordsCompleted);
this._cachedLoader = new DomainCollectionViewLoader<CachedKeywordResult>(LoadCachedKeywords, LoadCachedKeywordsCompleted);
this._feedSourceLoader = new DomainCollectionViewLoader<FeedSource>(LoadFeedSources, LoadFeedSourcesCompleted);

this._gnipRuleView = new DomainCollectionView<GnipRule>(this._gnipRuleLoader, this._gnipRuleSource);
this._keywordView = new DomainCollectionView<Keyword>(this._keywordLoader, this._keywordSource);
this._cachedView = new DomainCollectionView<CachedKeywordResult>(this._cachedLoader, this._cachedSource);
this._feedSourceView = new DomainCollectionView<FeedSource>(this._feedSourceLoader, this._feedSourceSource);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

撩人痒 2024-12-21 23:49:27

我在同一个地方,我正在考虑实现一个队列,只是因为这样我就可以确保我的操作可靠且按顺序提交。我做了一些研究,但尚未找到处理这种情况的好模式。

不过,您的回调模式似乎确实是一个简单的解决方法。 Hacky 缺乏结构,但如果您确保所有提交都通过一段代码,那么它应该很容易实现和维护。实现排队模式几乎肯定会更快。

检查IsSubmitting并避免SubmitChanges,让未提交的更改滚入下一个被调用的提交(如您所描述的),效果很好。不幸的是,它最终会导致一些未提交的更改(用户会话中的最后一个更改未保留,因为 IsSubmitting 当时为 true)。当这种情况发生时,这将是“运气不好”,特别是因为多次提交不太可能很快发生,但对于无法复制该错误的用户和测试人员来说,这将是非常烦人的。

I'm at the same place and I'm considering implementing a queue simply because I can then be sure that my operations are being committed reliably and in order. I've done a little bit of research and haven't yet found a nice pattern to deal with this situation.

Your callback pattern does seem like an easy workaround, though. Hacky in it's lack of structure, but if you ensure all submits go through a single piece of code then it should be easy enough to implement and maintain. It would almost certainly be quicker to implement that a queueing pattern.

Checking IsSubmitting and avoiding the SubmitChanges, to let the uncommitted change be rolled into the next submit that's called (as you describe) works fine. Unfortunately it will eventually lead to some uncommitted changes (the last change in a user's session wasn't persisted because IsSubmitting was true at that time). It would be 'bad luck' when that happens especially as it's unlikely that multiple submits will happen quickly, but it would be extremely annoying for users and testers who wouldn't be able to replicate the bug.

九公里浅绿 2024-12-21 23:49:27

像这样的事情怎么样?

if (!_serviceContext.IsSubmitting)
{
    _serviceContext.SubmitChanges();
}
else
{
    PropertyChangedEventHandler propChangedDelegate = null;
    propChangedDelegate = delegate
        {
            if (!_serviceContext.IsSubmitting)
            {
                _serviceContext.SubmitChanges();
                _serviceContext.PropertyChanged -= propChangedDelegate;
            }
        };
    _serviceContext.PropertyChanged += propChangedDelegate;

}

首先,我检查服务是否正在提交更改,如果是,我会订阅 PropertyChanged 事件,以便在 IsSubmitting 更改值时收到通知。从我所看到的来看,它似乎可以解决问题。

How about something like this?

if (!_serviceContext.IsSubmitting)
{
    _serviceContext.SubmitChanges();
}
else
{
    PropertyChangedEventHandler propChangedDelegate = null;
    propChangedDelegate = delegate
        {
            if (!_serviceContext.IsSubmitting)
            {
                _serviceContext.SubmitChanges();
                _serviceContext.PropertyChanged -= propChangedDelegate;
            }
        };
    _serviceContext.PropertyChanged += propChangedDelegate;

}

First I check if the service is submitting changes, if it is i subscribe to the PropertyChanged event to get notified when IsSubmitting changes value. From what i've seen it seems to do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文