山东雷驰
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.
 
 
 
 

728 lines
29 KiB

using AutoMapper;
using Kean.Domain;
using Kean.Domain.Stock.Models;
using Kean.Infrastructure.Database;
using Kean.Infrastructure.Database.Repository.Default;
using Kean.Infrastructure.Database.Repository.Default.Entities;
using Kean.Infrastructure.Database.Repository.Default.Entities.Interface;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
namespace Kean.Infrastructure.Repository
{
/// <summary>
/// 存储仓库
/// </summary>
public class StockRepository :
Domain.Stock.Repositories.IStockRepository
//Domain.Task.Repositories.IStockRepository
{
private readonly IMapper _mapper; // 模型映射
private readonly IDefaultDb _database; // 默认数据库
/// <summary>
/// 依赖注入
/// </summary>
public StockRepository(
IMapper mapper,
IDefaultDb database)
{
_mapper = mapper;
_database = database;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetBarcode 方法
*/
public async Task<string> GetBarcode(int cell)
{
return (await _database.From<T_STORAGE_MAIN>()
.Where(s => s.CELL_ID == cell)
.Single(s => new { s.STOCK_BARCODE }))?.STOCK_BARCODE;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetCell 方法
*/
public async Task<int?> GetCell(string barcode)
{
return (await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Single(s => new { s.CELL_ID }))?.CELL_ID;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetSpec 方法
*/
public async Task<int?> GetSpec(string barcode)
{
return (await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Single(s => new { s.STOCK_SPEC }))?.STOCK_SPEC;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetStock 方法
*/
public async Task<Stock> GetStock(string barcode)
{
var storageMain = await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Single();
if (storageMain == null)
{
return null;
}
var stock = _mapper.Map<Stock>(storageMain);
stock.Lines = _mapper.Map<IEnumerable<StockLine>>(await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_ID == storageMain.STORAGE_ID)
.Select());
return stock;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetLines 方法
*/
public async Task<IEnumerable<StockLine>> GetLines(string barcode)
{
var query = _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Query(s => s.STORAGE_ID);
return _mapper.Map<IEnumerable<StockLine>>(await _database.From<T_STORAGE_LIST>()
.Where(s => query.Contains(s.STORAGE_ID))
.Select());
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.CreateStock 方法
*/
public async Task CreateStock(Stock stock)
{
var timestamp = DateTime.Now;
int? id = (await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == stock.Barcode)
.Single(s => new { s.STORAGE_ID }))?
.STORAGE_ID;
if (!id.HasValue)
{
var storageMain = _mapper.Map<T_STORAGE_MAIN>(stock);
storageMain.CREATE_TIME = timestamp;
storageMain.UPDATE_TIME = timestamp;
id = Convert.ToInt32(await _database.From<T_STORAGE_MAIN>().Add(storageMain));
}
if (stock.Lines != null)
{
foreach (var item in stock.Lines)
{
if (item.Quantity <= 0)
{
throw new RepositoryException("入库数量必须表达为正数", new(nameof(item.Quantity), item.Quantity));
}
var storageList = _mapper.Map<T_STORAGE_LIST>(item);
if (storageList.STORAGE_LIST_ID == 0)
{
storageList.STORAGE_ID = id.Value;
storageList.INBOUND_TIME = item.InboundTime == default ? (item.InboundTime = stock.Timestamp) : item.InboundTime;
storageList.INVENTORY_TIME = stock.Timestamp;
storageList.CREATE_TIME = timestamp;
storageList.UPDATE_TIME = timestamp;
item.Id = Convert.ToInt32(await _database.From<T_STORAGE_LIST>().Add(storageList));
item.InventoryAge = 1 + (int)timestamp.Subtract(item.InboundTime).TotalDays;
if (item.ManufacturingDate.HasValue)
{
item.MaterialAge = 1 + (int)timestamp.Subtract(item.ManufacturingDate.Value).TotalDays;
}
}
else
{
var existence = await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_LIST_ID == storageList.STORAGE_LIST_ID && s.STORAGE_ID == id.Value)
.Single();
if (existence == null)
{
throw new RepositoryException("找不到库存行记录", new(nameof(item.Id), item.Id));
}
var quantity = item.Quantity;
_mapper.Map(existence, item).Quantity = quantity;
existence.STORAGE_LIST_QUANTITY += storageList.STORAGE_LIST_QUANTITY;
existence.INVENTORY_TIME = stock.Timestamp;
existence.UPDATE_TIME = timestamp;
await _database.From<T_STORAGE_LIST>().Update(existence);
}
}
}
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.DeleteStock 方法
*/
public async Task DeleteStock(Stock stock)
{
var timestamp = DateTime.Now;
if (stock.Lines == null)
{
int? storageid = (await _database.From<T_STORAGE_MAIN>()
.Where(r => r.STOCK_BARCODE == stock.Barcode)
.Single())?.STORAGE_ID;
await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_ID == storageid)
.Delete();
await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == stock.Barcode)
.Delete();
}
else
{
foreach (var item in stock.Lines)
{
if (item.Quantity >= 0)
{
throw new RepositoryException("出库数量必须表达为负数", new(nameof(item.Quantity), item.Quantity));
}
var existence = await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_LIST_ID == item.Id)
.Single();
if (existence == null)
{
throw new RepositoryException("找不到库存行记录", new(nameof(item.Id), item.Id));
}
if ((existence.STORAGE_LIST_QUANTITY += item.Quantity) < 0)
{
throw new RepositoryException("出库数量大于库存数量", new(nameof(item.Quantity), item.Quantity));
}
var quantity = item.Quantity;
_mapper.Map(existence, item).Quantity = quantity;
if (existence.STORAGE_LIST_QUANTITY == 0)
{
await _database.From<T_STORAGE_LIST>()
.Delete(existence);
}
else
{
existence.INVENTORY_TIME = stock.Timestamp;
existence.UPDATE_TIME = timestamp;
await _database.From<T_STORAGE_LIST>().Update(existence);
}
}
if ((await _database.From<T_STORAGE_MAIN, T_STORAGE_LIST>()
.Join(Join.Inner, (m, l) => m.STORAGE_ID == l.STORAGE_ID)
.Where((m, l) => m.STOCK_BARCODE == stock.Barcode)
.Single((m, l) => new { Count = Function.Count(l.STORAGE_LIST_ID) }))
.Count == 0)
{
await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == stock.Barcode)
.Delete();
}
else
{
await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == stock.Barcode)
.Update(new
{
FULL_FLAG = false,
UPDATE_TIME = timestamp
});
}
}
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.UpdateStock 方法
*/
public async Task UpdateStock(Stock stock)
{
var timestamp = DateTime.Now;
var properties = new Dictionary<string, (PropertyInfo entity, PropertyInfo model)>();
foreach (var item in stock.Lines)
{
var existence = await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_LIST_ID == item.Id)
.Single();
if (existence == null)
{
throw new RepositoryException("找不到库存行记录", new(nameof(item.Id), item.Id));
}
var remark = item.Remark as JObject;
var key = remark["property"]?.Value<string>();
if (!properties.ContainsKey(key))
{
if (!string.IsNullOrEmpty(key) && (_mapper.ConfigurationProvider as global::AutoMapper.Internal.IGlobalConfiguration)?
.FindTypeMapFor<T_STORAGE_LIST, StockLine>()?.PropertyMaps
.FirstOrDefault(p => p.DestinationName.Equals(key, StringComparison.OrdinalIgnoreCase))?
.CustomMapExpression.Body is MemberExpression expression)
{
properties.Add(key, (
typeof(T_STORAGE_LIST).GetProperty(expression.Member.Name),
typeof(StockLine).GetProperty(key, BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance))
);
}
else
{
throw new RepositoryException("找不到属性", new(nameof(item.Remark), item.Remark));
}
}
var (entity, model) = properties[key];
var oldValue = entity.GetValue(existence);
var newValue = model.GetValue(item);
if (newValue?.Equals(oldValue) == true)
{
var message = remark["message"]?.Value<string>();
if (!string.IsNullOrEmpty(message))
{
existence.STORAGE_LIST_REMARK = message;
existence.UPDATE_TIME = timestamp;
await _database.From<T_STORAGE_LIST>().Update(existence);
}
item.Id = -item.Id;
}
else
{
entity.SetValue(existence, newValue);
existence.INVENTORY_TIME = stock.Timestamp;
existence.STORAGE_LIST_REMARK += remark["message"]?.Value<string>();
existence.UPDATE_TIME = timestamp;
await _database.From<T_STORAGE_LIST>().Update(existence);
_mapper.Map(existence, item);
remark["@property"] = entity.Name;
remark["@value"] = JToken.FromObject(oldValue);
remark["@message"] = remark["message"];
}
}
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.SplitStock 方法
*/
public async Task<IEnumerable<Stock>> SplitStock(IEnumerable<StockLine> lines)
{
var stock = new Dictionary<int, Stock>();
foreach (var item in lines)
{
var existence = await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_LIST_ID == item.Id)
.Single();
if (existence == null)
{
throw new RepositoryException("找不到库存行记录", new(nameof(item.Id), item.Id));
}
if (!stock.ContainsKey(existence.STORAGE_ID))
{
stock.Add(existence.STORAGE_ID, _mapper.Map<Stock>(await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STORAGE_ID == existence.STORAGE_ID)
.Single()));
stock[existence.STORAGE_ID].Lines = new List<StockLine>();
}
var quantity = item.Quantity;
_mapper.Map(existence, item).Quantity = quantity;
(stock[existence.STORAGE_ID].Lines as List<StockLine>).Add(item);
}
return stock.Values;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.TakeStock 方法
*/
public async Task<IEnumerable<StockLine>> TakeStock(IEnumerable<StockLine> lines)
{
var dictionary = lines.ToDictionary(l => l.Id, l => l);
foreach (var item in await _database.From<T_STORAGE_LIST>()
.Where(l => dictionary.Keys.Contains(l.STORAGE_LIST_ID))
.Select())
{
var quantity = dictionary[item.STORAGE_LIST_ID].Quantity;
_mapper.Map(item, dictionary[item.STORAGE_LIST_ID]).Quantity = quantity - item.STORAGE_LIST_QUANTITY;
}
return lines;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.TransferStock 方法
*/
public async Task TransferStock(string barcode, int? spec, int destination)
{
await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Update(spec.HasValue ?
new
{
APPLYIN_LANEWAY = 0,
STOCK_SPEC = spec,
CELL_ID = destination,
UPDATE_TIME = DateTime.Now
} :
new
{
APPLYIN_LANEWAY = 0,
CELL_ID = destination,
UPDATE_TIME = DateTime.Now
});
}
///////////////////////////////////////////
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetCell 方法
*/
public async Task<int?> ChooseStorageCell(
int destination,
int goodsid,
bool bEnable,
string isLocal,
string materialType,// ok-正常物料0(合格) check-验证物料1(待检) ng-N G物料2(不合格)
string workOrderNo,
string qualityState,
string productDate) //N-不合格 Q-待检 Y-合格 M-免检
{
var goodType = await _database.From<T_GOODS_MAIN>().Where(r => r.GOODS_ID == goodsid).Single();
var stationsQuery = _database.From<T_WH_CELL>()
.Where(r => r.CELL_TYPE == "Station"
&& r.CELL_OUT == true
&& r.AREA_ID == destination)
.Query(r => r.CELL_ID);
var laneway = _database.From<IO_CONTROL_ROUTE>()
.Where(r => stationsQuery.Contains(r.END_DEVICE) && r.CONTROL_ROUTE_STATUS == 1 && r.CONTROL_ROUTE_TYPE == 2)
.Query(r => r.START_DEVICE);
var schema = _database.From<V_STORAGE_LIST>()
.Where(r => r.CELL_TYPE == nameof(Domain.Task.Models.Cell)
&& r.RUN_STATUS == nameof(Domain.Task.Enums.CellState.Enabled)
&& laneway.Contains(r.CELL_LANEWAY)
&& (r.STORAGE_LIST_FLAG == bEnable)
//&& (r.GOODS_SUPPLIER != "unupload" || r.GOODS_SUPPLIER == null)
//&& !manage.Contains(r.STOCK_BARCODE)
);
if (!string.IsNullOrEmpty(materialType))
{
schema.Where(r => r.GOODS_QC_STATE == materialType);
}
if (!string.IsNullOrEmpty(materialType) && materialType != "ng" && materialType != "check" && goodType.TYPE_ID != "4")
{
schema.Where(r=> r.GOODS_MFG >= DateTime.Now.AddDays(-7));
}
//@=@ 固定值 排除空托盘5,9
if (!string.IsNullOrEmpty(isLocal) && goodType.TYPE_ID != "4")
{
schema.Where(r => r.IS_LOCAL == isLocal);
}
if (goodsid > 0)
{
schema.Where(r => r.GOODS_ID == goodsid);
}
if (!string.IsNullOrEmpty(workOrderNo))
{
schema.Where(r => r.WORKORDER_NO == workOrderNo);
}
if (!string.IsNullOrEmpty(qualityState))
{
schema.Where(r => r.IS_AGV == qualityState);
}
if (!string.IsNullOrEmpty(productDate))
{
schema.Where(r => r.GOODS_MFG == Convert.ToDateTime(productDate));
}
//if (goodsid == 5 || goodsid == 9 || goodsid == 57 || goodsid == 58 || goodsid == 60 || goodsid == 61 || goodsid == 62)
if(goodType.TYPE_ID == "4")
{
schema = schema
.OrderBy(r => r.CELL_DEEP, Order.Descending)
.OrderBy(r => r.outerStatus, Order.Ascending)
.OrderBy(r => r.INBOUND_TIME, Order.Ascending);
}
else
{
schema = schema
.OrderBy(r => r.GOODS_MFG, Order.Ascending)
.OrderBy(r => r.INBOUND_TIME, Order.Ascending);
}
var cell = await schema.Select();
int? result = null;
//if (goodsid == 5 || goodsid == 9 || goodsid == 57 || goodsid == 58 || goodsid == 60 || goodsid == 61 || goodsid == 62)
if (goodType.TYPE_ID == "4")
{
var lanewayRoute = (await _database.From<IO_CONTROL_ROUTE>()
.Where(r => stationsQuery.Contains(r.END_DEVICE) && r.CONTROL_ROUTE_STATUS == 1 && r.CONTROL_ROUTE_TYPE == 2)
.Select())
.Select(r => new { CELL_LANEWAY = Convert.ToInt32(r.START_DEVICE) });
var lanewayManageCount = (await _database.From<V_MANAGE_MAIN>()
.Where(r => r.MANAGE_TYPE_CODE == "PalletOut")
.Select())
.GroupBy(r => r.LANEWAY).Select(r => new {
CELL_LANEWAY = r.Key,
LANEWAY_MANAGE_COUNT = r.Count()
});
List<dynamic> lsLaneway = new List<dynamic>();
foreach (var m in lanewayRoute)
{
int cell_laneway = m.CELL_LANEWAY;
int laneway_manage_count = 0;
var mc = lanewayManageCount.Where(r => r.CELL_LANEWAY == m.CELL_LANEWAY);
if (mc.Count() > 0)
{
laneway_manage_count = mc.First().LANEWAY_MANAGE_COUNT;
}
lsLaneway.Add(new
{
CELL_LANEWAY = cell_laneway,
LANEWAY_MANAGE_COUNT = laneway_manage_count
});
}
var query = from t in lsLaneway
orderby t.LANEWAY_MANAGE_COUNT
select t;
foreach (var m in query)
{
foreach (var row in cell.Where(r => r.CELL_LANEWAY == m.CELL_LANEWAY && (r.CELL_DEEP > 0 || r.CELL_DEEP == 0 && r.outerStatus != "Full")))
{
return result = row.CELL_ID;
}
}
}
foreach (var row in cell)
{
var differentList = await _database.From<V_STORAGE_LIST>()
.Where(r => r.STORAGE_ID == row.STORAGE_ID && r.GOODS_QC_STATE != row.GOODS_QC_STATE)
.Single();
if (differentList == null)
{
return result = row.CELL_ID;
}
}
return result;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetStorageMaterial 方法
*/
public async Task<int?> GetStorageMaterial(string barcode)
{
var cell = await _database.From<V_STORAGE_LIST>()
.Where(r => r.STOCK_BARCODE == barcode)
.Single();
return cell?.GOODS_ID;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetStorageBill 方法
*/
public async Task<Stock> GetStorageBill(string bill)
{
var storageList =await _database.From<T_STORAGE_LIST>()
.Where(r => r.GOODS_BILL_NO == bill)
.Select();
if (storageList == null || storageList.Count() ==0)
{
return null;
}
int storageId = storageList.First().STORAGE_ID;
var storageMain = await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STORAGE_ID == storageId)
.Single();
if (storageMain == null)
{
return null;
}
var stock = _mapper.Map<Stock>(storageMain);
stock.Lines = _mapper.Map<IEnumerable<StockLine>>(storageList);
return stock;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetStorageUnupload 方法
*/
public async Task<Stock> GetStorageUnupload(string barcode)
{
var storageMain = await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Single();
if (storageMain == null)
{
return null;
}
var stock = _mapper.Map<Stock>(storageMain);
stock.Lines = _mapper.Map<IEnumerable<StockLine>>(await _database.From<T_STORAGE_LIST>()
.Where(s => s.STORAGE_ID == storageMain.STORAGE_ID && s.GOODS_SUPPLIER == "unupload")
.Select());
return stock;
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetStorageLinesNum 方法
*/
public async Task<int> GetStorageLinesNum(int? cellId)
{
if (!cellId.HasValue)
{
return 0;
}
var storageList = await _database.From<V_STORAGE_LIST>()
.Where(s => s.CELL_ID == cellId)
.Select();
if (storageList == null)
{
return 0;
}
return storageList.Count();
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetQcBarcode 方法
*/
public async Task<IEnumerable<Stock>> GetQcBarcode(
int? goodsCode,
string batch,
DateTime? manufacturingDateFrom,
DateTime? manufacturingDateTo,
DateTime? inboundTimeFrom,
DateTime? inboundTimeTo,
string barcode,
string remark,
bool enable)
{
var schema = _database.From<V_STORAGE_LIST>();
if (goodsCode.HasValue)
{
schema = schema.Where(r => r.GOODS_ID == goodsCode);
}
if (batch != null)
{
schema = schema.Where(r => r.GOODS_BATCH_NO == batch);
}
if (manufacturingDateFrom.HasValue)
{
schema = schema.Where(r => r.GOODS_MFG >= manufacturingDateFrom.Value);
}
if (manufacturingDateTo.HasValue)
{
schema = schema.Where(r => r.GOODS_MFG <= manufacturingDateTo.Value.AddDays(1));
}
if (inboundTimeFrom.HasValue)
{
schema = schema.Where(r => r.INBOUND_TIME >= inboundTimeFrom.Value);
}
if (inboundTimeTo.HasValue)
{
schema = schema.Where(r => r.INBOUND_TIME <= inboundTimeTo.Value.AddDays(1));
}
if (barcode != null)
{
schema = schema.Where(r => r.STOCK_BARCODE == barcode);
}
if (enable && remark != null)
{
schema = schema.Where(r => r.STORAGE_LIST_REMARK.Contains(remark));
}
return _mapper.Map<IEnumerable<Stock>>(await schema.Distinct().Select());
}
///*
// * 实现 Kean.Domain.Stock.Repositories.IStockRepository.UpdateIsAgv 方法
// */
//public async Task UpdateIsAgv(string bill, string isAgv)
//{
// var driver = Infrastructure.Database.Configuration.Configure("Default");
// using (var context = driver.CreateContext())
// {
// await context.From<T_STORAGE_LIST>()
// .Where(r => r.GOODS_BILL_NO == bill)
// .Update(new
// {
// IS_AGV = isAgv,
// UPDATE_TIME = DateTime.Now
// });
// }
//}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.UpdateStorageProperty 方法
*/
public async Task UpdateStorageProperty(StockLine stockLine)
{
var storageList = await _database.From<T_STORAGE_LIST>()
.Where(r => r.GOODS_BILL_NO == stockLine.Bill)
.Select();
if (storageList == null || storageList.Count() == 0)
{
return;
}
var entity = _mapper.Map<T_STORAGE_LIST>(stockLine);
entity.STORAGE_ID = storageList.First().STORAGE_ID;
entity.UPDATE_TIME = DateTime.Now;
await _database.From<T_STORAGE_LIST>().Update(entity, nameof(T_GOODS_SAFETY.CREATE_TIME));
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.CleanTag 方法
*/
public async Task CleanTag(string barcode)
{
await _database.From<T_STORAGE_MAIN>()
.Where(s => s.STOCK_BARCODE == barcode)
.Update(
new
{
TAG = ""
});
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.GetErrFeedback 方法
*/
public async Task<ErrorFeedback> GetErrFeedback(int id)
{
var errFeedback = await _database.From<T_ERROR_FEEDBACK>()
.Where(s => s.ID == id)
.Single();
if (errFeedback == null)
{
return null;
}
return _mapper.Map<ErrorFeedback>(errFeedback);
}
/*
* 实现 Kean.Domain.Stock.Repositories.IStockRepository.IsPallet 方法
*/
public async Task<bool> IsPallet(int goodsid)
{
return (await _database.From<T_GOODS_MAIN, T_GOODS_CLASS>()
.Join(Join.Inner, (m, c) => m.CLASS_ID == c.CLASS_ID)
.Where((m, c) => c.CLASS_FLAG == true && m.GOODS_ID == goodsid && c.CLASS_PARENT_ID == 4)
.Single((m, c) => new { Count = Function.Count(c.CLASS_ID) })).Count > 0;
}
}
}