Skip to content

Commit 707e4d8

Browse files
committed
Fixed: Number of products per product tag could be incorrect in a multi-store
1 parent 5ddd776 commit 707e4d8

File tree

2 files changed

+36
-43
lines changed

2 files changed

+36
-43
lines changed

changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@
133133
* Customer could not delete his avatar
134134
* Facebook authentication: Email missing in verification
135135
* Attribute with a product linkage throws exception if added to cart
136+
* Number of products per product tag could be incorrect in a multi-store
136137

137138

138139
## SmartStore.NET 2.2.2

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

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@
1111

1212
namespace SmartStore.Services.Catalog
1313
{
14-
/// <summary>
15-
/// Product tag service
16-
/// </summary>
17-
public partial class ProductTagService : IProductTagService
14+
/// <summary>
15+
/// Product tag service
16+
/// </summary>
17+
public partial class ProductTagService : IProductTagService
1818
{
1919
#region Constants
2020

@@ -36,6 +36,7 @@ public partial class ProductTagService : IProductTagService
3636
#region Fields
3737

3838
private readonly IRepository<ProductTag> _productTagRepository;
39+
private readonly IRepository<StoreMapping> _storeMappingRepository;
3940
private readonly IDataProvider _dataProvider;
4041
private readonly IDbContext _dbContext;
4142
private readonly CommonSettings _commonSettings;
@@ -55,22 +56,29 @@ public partial class ProductTagService : IProductTagService
5556
/// <param name="commonSettings">Common settings</param>
5657
/// <param name="cacheManager">Cache manager</param>
5758
/// <param name="eventPublisher">Event published</param>
58-
public ProductTagService(IRepository<ProductTag> productTagRepository,
59+
public ProductTagService(
60+
IRepository<ProductTag> productTagRepository,
61+
IRepository<StoreMapping> storeMappingRepository,
5962
IDataProvider dataProvider,
6063
IDbContext dbContext,
6164
CommonSettings commonSettings,
6265
ICacheManager cacheManager,
6366
IEventPublisher eventPublisher)
6467
{
6568
_productTagRepository = productTagRepository;
69+
_storeMappingRepository = storeMappingRepository;
6670
_dataProvider = dataProvider;
6771
_dbContext = dbContext;
6872
_commonSettings = commonSettings;
6973
_cacheManager = cacheManager;
7074
_eventPublisher = eventPublisher;
71-
}
7275

73-
#endregion
76+
QuerySettings = DbQuerySettings.Default;
77+
}
78+
79+
public DbQuerySettings QuerySettings { get; set; }
80+
81+
#endregion
7482

7583
#region Nested classes
7684

@@ -94,55 +102,38 @@ private Dictionary<int, int> GetProductCount(int storeId)
94102
string key = string.Format(PRODUCTTAG_COUNT_KEY, storeId);
95103
return _cacheManager.Get(key, () =>
96104
{
105+
IEnumerable<ProductTagWithCount> tagCount = null;
97106

98107
if (_commonSettings.UseStoredProceduresIfSupported && _dataProvider.StoredProceduresSupported)
99108
{
100-
//stored procedures are enabled and supported by the database.
101-
//It's much faster than the LINQ implementation below
109+
//stored procedures are enabled and supported by the database. It's much faster than the LINQ implementation below
102110

103-
#region Use stored procedure
104-
105-
//prepare parameters
106111
var pStoreId = _dataProvider.GetParameter();
107112
pStoreId.ParameterName = "StoreId";
108113
pStoreId.Value = storeId;
109114
pStoreId.DbType = DbType.Int32;
110115

111-
112-
//invoke stored procedure
113-
var result = _dbContext.SqlQuery<ProductTagWithCount>(
114-
"Exec ProductTagCountLoadAll @StoreId",
115-
pStoreId);
116-
117-
var dictionary = new Dictionary<int, int>();
118-
foreach (var item in result)
119-
dictionary.Add(item.ProductTagId, item.ProductCount);
120-
return dictionary;
121-
122-
#endregion
116+
tagCount = _dbContext.SqlQuery<ProductTagWithCount>("Exec ProductTagCountLoadAll @StoreId", pStoreId);
123117
}
124118
else
125119
{
126120
//stored procedures aren't supported. Use LINQ
127-
#region Search products
128-
var query = from pt in _productTagRepository.Table
129-
select new
130-
{
131-
Id = pt.Id,
132-
ProductCount = pt.Products
133-
//published and not deleted product/variants
134-
.Count(p => !p.Deleted && p.Published)
135-
//UNDOEN filter by store identifier if specified ( > 0 )
136-
};
137-
138-
var dictionary = new Dictionary<int, int>();
139-
foreach (var item in query)
140-
dictionary.Add(item.Id, item.ProductCount);
141-
return dictionary;
142-
143-
#endregion
144121

122+
tagCount = _productTagRepository.Table
123+
.Select(pt => new ProductTagWithCount
124+
{
125+
ProductTagId = pt.Id,
126+
ProductCount = (storeId > 0 && !QuerySettings.IgnoreMultiStore) ?
127+
(from p in pt.Products
128+
join sm in _storeMappingRepository.Table on new { pid = p.Id, pname = "Product" } equals new { pid = sm.EntityId, pname = sm.EntityName } into psm
129+
from sm in psm.DefaultIfEmpty()
130+
where (!p.LimitedToStores || storeId == sm.StoreId) && !p.Deleted && p.Published
131+
select p).Count() :
132+
pt.Products.Count(p => !p.Deleted && p.Published)
133+
});
145134
}
135+
136+
return tagCount.ToDictionary(x => x.ProductTagId, x => x.ProductCount);
146137
});
147138
}
148139

@@ -265,10 +256,11 @@ public virtual void UpdateProductTag(ProductTag productTag)
265256
public virtual int GetProductCount(int productTagId, int storeId)
266257
{
267258
var dictionary = GetProductCount(storeId);
259+
268260
if (dictionary.ContainsKey(productTagId))
269261
return dictionary[productTagId];
270-
else
271-
return 0;
262+
263+
return 0;
272264
}
273265

274266
#endregion

0 commit comments

Comments
 (0)