NopCommerce 4.x - SaveAttribute
db.Customer.find()
[
{
_id: ObjectId('5f4f9b12391cb72c24428b2d'),
GenericAttributes: [
{
Key: 'LanguageId',
Value: '5cf6adc550f62850c08d1153',
StoreId: ObjectId('5cf6adc450f62850c08d1152')
}
],
step 1.GenericAttribute
\src\Libraries\Nop.Core\Domain\Common\GenericAttribute.cs
using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
namespace Nop.Core.Domain.Common
{ /// <summary>
/// Represents a generic attribute
/// </summary>
[BsonIgnoreExtraElements]
public partial class GenericAttribute
{
/// <summary>
/// Gets or sets the entity identifier
/// </summary>
//public string EntityId { get; set; }
/// <summary>
/// Gets or sets the key group
/// </summary>
//public string KeyGroup { get; set; }
/// <summary>
/// Gets or sets the key
/// </summary>
public string Key { get; set; }
/// <summary>
/// Gets or sets the value
/// </summary>
public string Value { get; set; }
/// <summary>
/// Gets or sets the store identifier
/// </summary>
public ObjectId StoreId { get; set; }
}
}
2
src\Libraries\Nop.Core\BaseEntity.cs
namespace Nop.Core
{
/// <summary>
/// Base class for entities
/// </summary>
[BsonIgnoreExtraElements]
public abstract partial class BaseEntity: ParentEntity
{
public BaseEntity()
{
GenericAttributes = new List<GenericAttribute>();
}
public IList<GenericAttribute> GenericAttributes { get; set; }
3
\src\Libraries\Nop.Core\Domain\Customers\Customer.cs
public partial class Customer : BaseEntity
{
src\Libraries\Nop.Services\Common\GenericAttributeService.cs
namespace Nop.Services.Common
{
/// <summary>
/// Generic attribute service
/// </summary>
public partial class GenericAttributeService : IGenericAttributeService
{
private const string CUSTOMER_COOKIE_NAME1 = "Nop.customer";
#region Fields
private readonly IRepository<BaseEntity> _baseRepository;
private readonly IRepository<GenericAttributeBaseEntity> _genericattributeBaseEntitRepository;
private readonly IEventPublisher _eventPublisher;
#endregion
#region Ctor
/// <summary>
/// Ctor
/// </summary>
/// <param name="genericAttributeRepository">Generic attribute repository</param>
/// <param name="GenericAttributeBaseEntity">Generic attribute base repository</param>
/// <param name="eventPublisher">Event published</param>
public GenericAttributeService(
IRepository<BaseEntity> baseRepository,
IRepository<GenericAttributeBaseEntity> genericattributeBaseEntitRepository,
IEventPublisher eventPublisher)
{
this._baseRepository = baseRepository;
this._genericattributeBaseEntitRepository = genericattributeBaseEntitRepository;
this._eventPublisher = eventPublisher;
}
#endregion
#region Methods
/// <summary>
/// Save attribute value
/// </summary>
/// <typeparam name="TPropType">Property type</typeparam>
/// <param name="entity">Entity</param>
/// <param name="key">Key</param>
/// <param name="value">Value</param>
/// <param name="storeId">Store identifier; pass 0 if this attribute will be available for all stores</param>
public virtual void SaveAttribute<TPropType>(BaseEntity entity, string key, TPropType value, string storeId = "")
{
if (entity == null)
throw new ArgumentNullException("entity");
if (key == null)
throw new ArgumentNullException("key");
string keyGroup = entity.GetType().Name;
var collection = _baseRepository.Database.GetCollection<GenericAttributeBaseEntity>(keyGroup);
var query = _baseRepository.Database.GetCollection<GenericAttributeBaseEntity>(keyGroup).AsQueryable();
var props = query.Where(x => x.Id == entity.Id).SelectMany(x => x.GenericAttributes).ToList();
var prop = props.FirstOrDefault(ga =>
ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)); //should be culture invariant
var valueStr = CommonHelper.To<string>(value);
if (prop != null)
{
if (string.IsNullOrWhiteSpace(valueStr))
{
//delete
var builder = Builders<GenericAttributeBaseEntity>.Update;
var updatefilter = builder.PullFilter(x => x.GenericAttributes, y => y.Key == prop.Key && y.StoreId == new ObjectId(storeId));
var result = collection.UpdateManyAsync(new BsonDocument("_id", entity.Id), updatefilter).Result;
}
else
{
//update
prop.Value = valueStr;
var builder = Builders<GenericAttributeBaseEntity>.Filter;
var filter = builder.Eq(x => x.Id, entity.Id);
filter = filter & builder.Where(x => x.GenericAttributes.Any(y => y.Key == prop.Key));
var update = Builders<GenericAttributeBaseEntity>.Update
.Set(x => x.GenericAttributes.ElementAt(-1).Value, prop.Value);
var result = collection.UpdateManyAsync(filter, update).Result;
}
}
else
{
if (!string.IsNullOrWhiteSpace(valueStr))
{
prop = new GenericAttribute
{
Key = key,
Value = valueStr,
StoreId = new ObjectId(storeId),
};
var updatebuilder = Builders<GenericAttributeBaseEntity>.Update;
var update = updatebuilder.AddToSet(p => p.GenericAttributes, prop);
var result = collection.UpdateOneAsync(new BsonDocument("_id", entity.Id), update).Result;
}
}
}
public virtual TPropType GetAttributesForEntity<TPropType>(BaseEntity entity, string key, string storeId = "")
{
if (entity == null)
throw new ArgumentNullException("entity");
var collection = _genericattributeBaseEntitRepository.Database.GetCollection<GenericAttributeBaseEntity>(entity.GetType().Name).AsQueryable();
var props = collection.Where(x => x.Id == entity.Id).SelectMany(x => x.GenericAttributes).ToList();
if (props == null)
return default(TPropType);
// props = props.Where(x => x.StoreId == new ObjectId(storeId)).ToList();
if (!String.IsNullOrEmpty(storeId)) //add by freeman 2019/05/12
props = props.Where(x => x.StoreId == new ObjectId(storeId)).ToList();
if (!props.Any())
return default(TPropType);
var prop = props.FirstOrDefault(ga =>
ga.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase));
if (prop == null || string.IsNullOrEmpty(prop.Value))
return default(TPropType);
return CommonHelper.To<TPropType>(prop.Value);
}
#endregion
}
}
\src\Presentation\Nop.Web\Controllers\CustomerController.cs
string customerAvatarId = "";
if (customerAvatar != null)
customerAvatarId = customerAvatar.Id.ToString();
_genericAttributeService.SaveAttribute(customer, SystemCustomerAttributeNames.AvatarPictureId, customerAvatarId,"");
https://github.com/nopSolutions/nopCommerce/blob/0af5948207ad60d7b3079e4e71a8409dcd04351a/src/Presentation/Nop.Web/Areas/Admin/Controllers/HomeController.cs#L87
await _genericAttributeService.SaveAttributeAsync(currentLanguage, NopCommonDefaults.LanguagePackProgressAttribute, string.Empty);