Skip to content

Commit dd700bb

Browse files
committed
Perf: more optimizations
1 parent a533d62 commit dd700bb

15 files changed

Lines changed: 195 additions & 77 deletions

File tree

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
3+
namespace SmartStore.Core.Data
4+
{
5+
public class DbQuerySettings
6+
{
7+
private readonly static DbQuerySettings s_default = new DbQuerySettings(false, false);
8+
9+
public DbQuerySettings(bool ignoreAcl, bool ignoreMultiStore)
10+
{
11+
this.IgnoreAcl = ignoreAcl;
12+
this.IgnoreMultiStore = ignoreMultiStore;
13+
}
14+
15+
public bool IgnoreAcl { get; private set; }
16+
public bool IgnoreMultiStore { get; private set; }
17+
18+
public static DbQuerySettings Default
19+
{
20+
get { return s_default; }
21+
}
22+
}
23+
}

src/Libraries/SmartStore.Core/SmartStore.Core.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@
136136
<Compile Include="Configuration\ISettingService.cs" />
137137
<Compile Include="Configuration\JsonPersistAttribute.cs" />
138138
<Compile Include="Data\DbContextScope.cs" />
139+
<Compile Include="Data\DbQuerySettings.cs" />
139140
<Compile Include="Data\EntityState.cs" />
140141
<Compile Include="Data\Hooks\HookedEntityEntry.cs" />
141142
<Compile Include="Data\Hooks\HookEntityMetadata.cs" />

src/Libraries/SmartStore.Services/Blogs/BlogService.cs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,12 @@ public BlogService(IRepository<BlogPost> blogPostRepository,
3636
_storeMappingRepository = storeMappingRepository;
3737
_cacheManager = cacheManager;
3838
_eventPublisher = eventPublisher;
39+
40+
this.QuerySettings = DbQuerySettings.Default;
3941
}
4042

43+
public DbQuerySettings QuerySettings { get; set; }
44+
4145
#endregion
4246

4347
#region Methods
@@ -98,7 +102,7 @@ public virtual IPagedList<BlogPost> GetAllBlogPosts(int storeId, int languageId,
98102
query = query.Where(b => !b.EndDateUtc.HasValue || b.EndDateUtc >= utcNow);
99103
}
100104

101-
if (storeId > 0)
105+
if (storeId > 0 && !QuerySettings.IgnoreMultiStore)
102106
{
103107
//Store mapping
104108
query = from bp in query

src/Libraries/SmartStore.Services/Catalog/CategoryService.cs

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,12 @@ public CategoryService(ICacheManager cacheManager,
8484
this._storeMappingService = storeMappingService;
8585
this._aclService = aclService;
8686
this._navigationFilters = navigationFilters;
87+
88+
this.QuerySettings = DbQuerySettings.Default;
8789
}
8890

91+
public DbQuerySettings QuerySettings { get; set; }
92+
8993
#endregion
9094

9195
#region Methods
@@ -182,24 +186,29 @@ public IList<Category> GetAllCategoriesByParentCategoryId(int parentCategoryId,
182186
protected virtual IQueryable<Category> ApplyHiddenCategoriesFilter(IQueryable<Category> query, bool applyNavigationFilters)
183187
{
184188
// ACL (access control list)
185-
var allowedCustomerRolesIds = _workContext.CurrentCustomer.CustomerRoles
186-
.Where(cr => cr.Active).Select(cr => cr.Id).ToList();
189+
var allowedCustomerRolesIds = _workContext.CurrentCustomer.CustomerRoles.Where(x => x.Active).Select(x => x.Id).ToList();
187190

188-
query = from c in query
189-
join acl in _aclRepository.Table
190-
on new { c1 = c.Id, c2 = "Category" } equals new { c1 = acl.EntityId, c2 = acl.EntityName } into c_acl
191-
from acl in c_acl.DefaultIfEmpty()
192-
where !c.SubjectToAcl || allowedCustomerRolesIds.Contains(acl.CustomerRoleId)
193-
select c;
191+
if (!QuerySettings.IgnoreAcl)
192+
{
193+
query = from c in query
194+
join acl in _aclRepository.Table
195+
on new { c1 = c.Id, c2 = "Category" } equals new { c1 = acl.EntityId, c2 = acl.EntityName } into c_acl
196+
from acl in c_acl.DefaultIfEmpty()
197+
where !c.SubjectToAcl || allowedCustomerRolesIds.Contains(acl.CustomerRoleId)
198+
select c;
199+
}
194200

195-
//Store mapping
196-
var currentStoreId = _storeContext.CurrentStore.Id;
197-
query = from c in query
198-
join sm in _storeMappingRepository.Table
199-
on new { c1 = c.Id, c2 = "Category" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into c_sm
200-
from sm in c_sm.DefaultIfEmpty()
201-
where !c.LimitedToStores || currentStoreId == sm.StoreId
202-
select c;
201+
if (!QuerySettings.IgnoreMultiStore)
202+
{
203+
//Store mapping
204+
var currentStoreId = _storeContext.CurrentStore.Id;
205+
query = from c in query
206+
join sm in _storeMappingRepository.Table
207+
on new { c1 = c.Id, c2 = "Category" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into c_sm
208+
from sm in c_sm.DefaultIfEmpty()
209+
where !c.LimitedToStores || currentStoreId == sm.StoreId
210+
select c;
211+
}
203212

204213
//only distinct categories (group by ID)
205214
query = from c in query

src/Libraries/SmartStore.Services/Catalog/ManufacturerService.cs

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,12 @@ public ManufacturerService(ICacheManager cacheManager,
6666
_workContext = workContext;
6767
_storeContext = storeContext;
6868
_eventPublisher = eventPublisher;
69-
}
69+
70+
this.QuerySettings = DbQuerySettings.Default;
71+
}
72+
73+
public DbQuerySettings QuerySettings { get; set; }
74+
7075
#endregion
7176

7277
#region Methods
@@ -114,14 +119,16 @@ public virtual IList<Manufacturer> GetAllManufacturers(string manufacturerName,
114119
if (!showHidden)
115120
{
116121
//Store mapping
117-
var currentStoreId = _storeContext.CurrentStore.Id;
118-
119-
query = from m in query
120-
join sm in _storeMappingRepository.Table
121-
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
122-
from sm in m_sm.DefaultIfEmpty()
123-
where !m.LimitedToStores || currentStoreId == sm.StoreId
124-
select m;
122+
if (!QuerySettings.IgnoreMultiStore)
123+
{
124+
var currentStoreId = _storeContext.CurrentStore.Id;
125+
query = from m in query
126+
join sm in _storeMappingRepository.Table
127+
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
128+
from sm in m_sm.DefaultIfEmpty()
129+
where !m.LimitedToStores || currentStoreId == sm.StoreId
130+
select m;
131+
}
125132

126133
//only distinct manufacturers (group by ID)
127134
query = from m in query
@@ -251,16 +258,18 @@ orderby pm.DisplayOrder
251258

252259
if (!showHidden)
253260
{
254-
//Store mapping
255-
var currentStoreId = _storeContext.CurrentStore.Id;
256-
257-
query = from pm in query
258-
join m in _manufacturerRepository.Table on pm.ManufacturerId equals m.Id
259-
join sm in _storeMappingRepository.Table
260-
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
261-
from sm in m_sm.DefaultIfEmpty()
262-
where !m.LimitedToStores || currentStoreId == sm.StoreId
263-
select pm;
261+
if (!QuerySettings.IgnoreMultiStore)
262+
{
263+
//Store mapping
264+
var currentStoreId = _storeContext.CurrentStore.Id;
265+
query = from pm in query
266+
join m in _manufacturerRepository.Table on pm.ManufacturerId equals m.Id
267+
join sm in _storeMappingRepository.Table
268+
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
269+
from sm in m_sm.DefaultIfEmpty()
270+
where !m.LimitedToStores || currentStoreId == sm.StoreId
271+
select pm;
272+
}
264273

265274
//only distinct manufacturers (group by ID)
266275
query = from pm in query
@@ -301,16 +310,18 @@ orderby pm.DisplayOrder
301310

302311
if (!showHidden)
303312
{
304-
//Store mapping
305-
var currentStoreId = _storeContext.CurrentStore.Id;
306-
307-
query = from pm in query
308-
join m in _manufacturerRepository.Table on pm.ManufacturerId equals m.Id
309-
join sm in _storeMappingRepository.Table
310-
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
311-
from sm in m_sm.DefaultIfEmpty()
312-
where !m.LimitedToStores || currentStoreId == sm.StoreId
313-
select pm;
313+
if (!QuerySettings.IgnoreMultiStore)
314+
{
315+
//Store mapping
316+
var currentStoreId = _storeContext.CurrentStore.Id;
317+
query = from pm in query
318+
join m in _manufacturerRepository.Table on pm.ManufacturerId equals m.Id
319+
join sm in _storeMappingRepository.Table
320+
on new { c1 = m.Id, c2 = "Manufacturer" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into m_sm
321+
from sm in m_sm.DefaultIfEmpty()
322+
where !m.LimitedToStores || currentStoreId == sm.StoreId
323+
select pm;
324+
}
314325

315326
//only distinct manufacturers (group by ID)
316327
query = from pm in query

src/Libraries/SmartStore.Services/Catalog/ProductService.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,12 @@ public ProductService(ICacheManager cacheManager,
131131
this._localizationSettings = localizationSettings;
132132
this._commonSettings = commonSettings;
133133
this._eventPublisher = eventPublisher;
134+
135+
this.QuerySettings = DbQuerySettings.Default;
134136
}
135137

138+
public DbQuerySettings QuerySettings { get; set; }
139+
136140
#endregion
137141

138142
private List<int> AllowedRoleIds {
@@ -436,7 +440,7 @@ public virtual IPagedList<Product> SearchProducts(ProductSearchContext ctx)
436440

437441
var pStoreId = _dataProvider.GetParameter();
438442
pStoreId.ParameterName = "StoreId";
439-
pStoreId.Value = ctx.StoreId;
443+
pStoreId.Value = QuerySettings.IgnoreMultiStore ? 0 : ctx.StoreId;
440444
pStoreId.DbType = DbType.Int32;
441445

442446
var pParentGroupedProductId = _dataProvider.GetParameter();
@@ -799,7 +803,7 @@ from pt in p.ProductTags.DefaultIfEmpty()
799803
select p;
800804
}
801805

802-
if (!ctx.ShowHidden)
806+
if (!ctx.ShowHidden && !QuerySettings.IgnoreAcl)
803807
{
804808
// ACL
805809
query = from p in query
@@ -809,7 +813,7 @@ from acl in p_acl.DefaultIfEmpty()
809813
select p;
810814
}
811815

812-
if (ctx.StoreId > 0)
816+
if (ctx.StoreId > 0 && !QuerySettings.IgnoreMultiStore)
813817
{
814818
//Store mapping
815819
query = from p in query

src/Libraries/SmartStore.Services/Messages/MessageTemplateService.cs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ public MessageTemplateService(ICacheManager cacheManager,
6060
this._storeMappingService = storeMappingService;
6161
this._messageTemplateRepository = messageTemplateRepository;
6262
this._eventPublisher = eventPublisher;
63-
}
63+
64+
this.QuerySettings = DbQuerySettings.Default;
65+
}
66+
67+
public DbQuerySettings QuerySettings { get; set; }
6468

6569
#endregion
6670

@@ -147,25 +151,15 @@ public virtual MessageTemplate GetMessageTemplateByName(string messageTemplateNa
147151
var query = _messageTemplateRepository.Table;
148152
query = query.Where(t => t.Name == messageTemplateName);
149153
query = query.OrderBy(t => t.Id);
154+
var templates = query.ToList();
150155

151-
//Store mapping
156+
//store mapping
152157
if (storeId > 0)
153158
{
154-
query = from t in query
155-
join sm in _storeMappingRepository.Table
156-
on new { c1 = t.Id, c2 = "MessageTemplate" } equals new { c1 = sm.EntityId, c2 = sm.EntityName } into t_sm
157-
from sm in t_sm.DefaultIfEmpty()
158-
where !t.LimitedToStores || storeId == sm.StoreId
159-
select t;
160-
161-
//only distinct items (group by ID)
162-
query = from t in query
163-
group t by t.Id into tGroup
164-
orderby tGroup.Key
165-
select tGroup.FirstOrDefault();
166-
query = query.OrderBy(t => t.Id);
159+
return templates.Where(t => _storeMappingService.Authorize(t, storeId)).FirstOrDefault();
167160
}
168-
return query.FirstOrDefault();
161+
162+
return templates.FirstOrDefault();
169163
});
170164

171165
}
@@ -184,7 +178,7 @@ public virtual IList<MessageTemplate> GetAllMessageTemplates(int storeId)
184178
query = query.OrderBy(t => t.Name);
185179

186180
//Store mapping
187-
if (storeId > 0)
181+
if (storeId > 0 && !QuerySettings.IgnoreMultiStore)
188182
{
189183
query = from t in query
190184
join sm in _storeMappingRepository.Table

src/Libraries/SmartStore.Services/News/NewsService.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,11 @@ public NewsService(IRepository<NewsItem> newsItemRepository,
3434
_storeMappingRepository = storeMappingRepository;
3535
_cacheManager = cacheManager;
3636
_eventPublisher = eventPublisher;
37-
}
37+
38+
this.QuerySettings = DbQuerySettings.Default;
39+
}
40+
41+
public DbQuerySettings QuerySettings { get; set; }
3842

3943
#endregion
4044

@@ -93,7 +97,7 @@ public virtual IPagedList<NewsItem> GetAllNews(int languageId, int storeId,
9397
query = query.OrderByDescending(n => n.CreatedOnUtc);
9498

9599
//Store mapping
96-
if (storeId > 0)
100+
if (storeId > 0 && !QuerySettings.IgnoreMultiStore)
97101
{
98102
query = from n in query
99103
join sm in _storeMappingRepository.Table

src/Libraries/SmartStore.Services/Security/AclService.cs

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public partial class AclService : IAclService
2626
private readonly IRepository<AclRecord> _aclRecordRepository;
2727
private readonly IWorkContext _workContext;
2828
private readonly ICacheManager _cacheManager;
29+
private bool? _hasActiveAcl;
2930

3031
#endregion
3132

@@ -43,11 +44,28 @@ public AclService(ICacheManager cacheManager, IWorkContext workContext,
4344
this._cacheManager = cacheManager;
4445
this._workContext = workContext;
4546
this._aclRecordRepository = aclRecordRepository;
46-
}
47+
48+
this.QuerySettings = DbQuerySettings.Default;
49+
}
50+
51+
public DbQuerySettings QuerySettings { get; set; }
4752

4853
#endregion
4954

50-
#region Methods
55+
#region Members
56+
57+
public bool HasActiveAcl
58+
{
59+
get
60+
{
61+
if (!_hasActiveAcl.HasValue)
62+
{
63+
var query = _aclRecordRepository.Where(x => true /* TODO: IsActive field */);
64+
_hasActiveAcl = query.Any();
65+
}
66+
return _hasActiveAcl.Value;
67+
}
68+
}
5169

5270
/// <summary>
5371
/// Deletes an ACL record
@@ -213,6 +231,9 @@ public virtual bool Authorize<T>(T entity, Customer customer) where T : BaseEnti
213231
if (customer == null)
214232
return false;
215233

234+
if (QuerySettings.IgnoreAcl)
235+
return true;
236+
216237
if (!entity.SubjectToAcl)
217238
return true;
218239

src/Libraries/SmartStore.Services/Security/IAclService.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,12 @@ namespace SmartStore.Services.Security
1515
/// </summary>
1616
public partial interface IAclService
1717
{
18-
/// <summary>
18+
/// <summary>
19+
/// Gets a value indicating whether at least one ACL record is in active state system-wide
20+
/// </summary>
21+
bool HasActiveAcl { get; }
22+
23+
/// <summary>
1924
/// Deletes an ACL record
2025
/// </summary>
2126
/// <param name="aclRecord">ACL record</param>

0 commit comments

Comments
 (0)