You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
4.7 KiB

2 years ago
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Linq.Expressions;
using Volo.Abp.Domain.Entities;
using Volo.Abp.Guids;
using Win_in.Sfs.Shared.Domain.Entities;
namespace Win_in.Sfs.Shared.Domain;
public abstract class SfsMasterAggregateRootBase<TDetail> : SfsAggregateRootBase
, IMasterEntity<TDetail>, IHasNumber, IHasWorker
where TDetail : SfsDetailEntityBase, IEntity<Guid>
{
/// <summary>
/// 操作员
/// </summary>
[IgnoreUpdate]
public string Worker { get; set; }
/// <summary>
/// 单据号
/// </summary>
[IgnoreUpdate]
public string Number { get; set; }
[IgnoreUpdate]
public virtual List<TDetail> Details { get; set; } = new();
private void SetIdAndNumber(IGuidGenerator guidGenerator, string number)
{
Id = guidGenerator.Create();
Number = number;
}
public virtual void SetIdAndNumberWithDetails(IGuidGenerator guidGenerator, string number)
{
SetIdAndNumber(guidGenerator, number);
SetDetailsIdAndNumber(guidGenerator);
}
private void SetDetailsIdAndNumber(IGuidGenerator guidGenerator)
{
foreach (var detail in Details)
{
detail.SetIdAndNumber(guidGenerator, Id, Number);
}
}
public TDetail GetDetail(Guid id)
{
return Details.FirstOrDefault(p => p.Id == id);
}
public bool AddDetail(TDetail detail)
{
//todo check
return Details.AddIfNotContains(detail);
}
public void AddDetails(List<TDetail> details)
{
//todo check
Details.AddRange(details);
}
public void ReplaceDetail(Guid id,TDetail newDetail)
2 years ago
{
var detail = GetDetail(id);
var propertiesOfDetail = detail.GetType().GetProperties();
var propertiesOfNewDetail = newDetail.GetType().GetProperties();
foreach (var property in propertiesOfDetail)
{
if (property.Name == "Id" || property.Name == "TenantId" || !property.CanWrite)
{
continue;
}
var attributes = property.GetCustomAttributes(typeof(NotMappedAttribute), false);
if (attributes.Any())
{
continue;
}
var propertyOfNewDetail = propertiesOfNewDetail.SingleOrDefault(y => y.Name == property.Name);
if (propertyOfNewDetail == null)
{
continue;
}
var oldValue = property.GetValue(detail);
var newValue = propertyOfNewDetail.GetValue(newDetail);
if (oldValue == null && newValue == null)
{
property.SetValue(detail, null);
}
else
{
if (oldValue.Equals(newValue))
{
continue;
}
property.SetValue(detail, newValue);
}
}
/*
////todo check
//var detail = GetDetail(id);
////todo DeepClone
//detail = newDetail;
Details.ForEach(x =>
{
if (x.Id != id) return;
var propertyInfoOrigins = x.GetType().GetProperties();
foreach (var propertyInfo in propertyInfoOrigins)
{
var targetPropertyIn = propertyInfoTargets.SingleOrDefault(y => y.Name == propertyInfo.Name);
if (targetPropertyIn == null
|| propertyInfo.Name == "TenantId"
|| propertyInfo.Name == "MasterID")
{
continue;
}
if (!targetPropertyIn.CanWrite)
{
continue;
}
var attributes = propertyInfo.GetCustomAttributes(typeof(NotMappedAttribute), false);
if (attributes.Any())
{
continue;
}
propertyInfo.SetValue(x, targetPropertyIn.GetValue(newDetail));
}
});*/
}
public void RemoveDetail(Guid id)
{
//todo check
var detail = GetDetail(id);
Details.Remove(detail);
}
public bool IsInDetails(Guid id)
{
return GetDetail(id) != null;
}
public bool IsInDetails(Expression<Func<TDetail, bool>> expression)
{
return Details.Any(expression.Compile());
}
public long GetDetailCount(Expression<Func<TDetail, bool>> expression)
{
return Details.Count(expression.Compile());
}
public List<TDetail> GetDetailList(Expression<Func<TDetail, bool>> expression)
{
return Details.Where(expression.Compile()).ToList();
}
}