public ActionResult Edit(int id)
        {
            var entity = _prodpropertyvalRepo.Get(pv => pv.Status != (int)DataStatus.Deleted)
                        .Join(_prodpropertyRepo.Get(p => p.Status != (int)DataStatus.Deleted && p.ProductId == id), o => o.PropertyId, i => i.Id, (o, i) => new { PV = o, P = i });
            ProductPropertyViewModel vo = new ProductPropertyViewModel();
            var prodEntity = _prodRepo.Find(id);
            vo.Values = new List<TagPropertyValueViewModel>();
            vo.ProductId = prodEntity.Id;
            vo.ProductName = prodEntity.Name;
            foreach (var l in entity)
            {
                var newValue = new TagPropertyValueViewModel().FromEntity<TagPropertyValueViewModel>(l.PV, p =>
                {
                    p.PropertyDesc = l.P.PropertyDesc;
                    p.SortOrder = l.P.SortOrder??0;
                    p.PropertyId = l.P.Id;
                    p.ValueId = l.PV.Id;
                });
                vo.Values.Add(newValue);
            }

            return View(vo);
        }
        public ActionResult Edit(FormCollection formCollection, ProductPropertyViewModel vo)
        {
            if (!ModelState.IsValid)
            {
                return View(vo);
            }

            using (var ts = new TransactionScope())
            {
                //step1: find the properties to delete
                IEnumerable<string> newProperty = vo.Values.Where(o=>o.Status!=(int)DataStatus.Deleted).Select(o => o.PropertyDesc).Distinct();
                IQueryable<ProductPropertyEntity> catProperties = _prodpropertyRepo.Get(t => t.ProductId == vo.ProductId && t.Status != (int)DataStatus.Deleted);
                IEnumerable<string> existProperty = catProperties.Select(o => o.PropertyDesc);
                IEnumerable<string> toDeleted = existProperty.Except(newProperty);

                foreach (var diff in toDeleted)
                {
                    var todeleteProperty = catProperties.Where(p => p.PropertyDesc == diff).FirstOrDefault();
                    if (todeleteProperty != null)
                    {
                        todeleteProperty.Status = (int)DataStatus.Deleted;
                        todeleteProperty.UpdateDate = DateTime.Now;
                        _prodpropertyRepo.Update(todeleteProperty);
                        //cascad delete values
                        foreach (var deleteValue in _prodpropertyvalRepo.Get(t => t.PropertyId == todeleteProperty.Id && t.Status != (int)DataStatus.Deleted))
                        {
                            deleteValue.Status = (int)DataStatus.Deleted;
                            deleteValue.UpdateDate = DateTime.Now;
                            _prodpropertyvalRepo.Update(deleteValue);
                        }
                    }
                }
                // step2: find the properties to insert
                foreach(var diff in newProperty.Except(existProperty))
                {
                    var insertProperty = _prodpropertyRepo.Insert(new ProductPropertyEntity(){
                         ProductId = vo.ProductId,
                             PropertyDesc = diff,
                              SortOrder =0,
                               Status=(int)DataStatus.Normal,
                                UpdateDate = DateTime.Now,
                                UpdateUser =CurrentUser.CustomerId

                    });
                    //insert values
                    foreach(var insertValue in vo.Values.Where(o=>o.PropertyDesc == diff && o.Status!=(int)DataStatus.Deleted))
                    {
                        _prodpropertyvalRepo.Insert(new ProductPropertyValueEntity(){
                             CreateDate = DateTime.Now,
                               PropertyId = insertProperty.Id,
                                 Status = (int)DataStatus.Normal,
                                  UpdateDate = DateTime.Now,
                                    ValueDesc = insertValue.ValueDesc
                        });
                    }
                }
                //step3: update exist properties
                foreach(var diff in newProperty.Intersect(existProperty))
                {
                    var propertyEntity = catProperties.Where(p => p.PropertyDesc == diff).FirstOrDefault();
                    IEnumerable<string> newValue = vo.Values.Where(o=>o.Status!=(int)DataStatus.Deleted && o.PropertyDesc==diff).Select(o => o.ValueDesc).Distinct();
                    IQueryable<ProductPropertyValueEntity> catPropertyValues = _prodpropertyvalRepo.Get(t => t.PropertyId == propertyEntity.Id && t.Status != (int)DataStatus.Deleted);
                     IEnumerable<string> existValue = catPropertyValues.Select(o => o.ValueDesc);
                    foreach(var diffvalue in existValue.Except(newValue))
                    {
                        var todeletevalue = catPropertyValues.Where(o=>o.ValueDesc == diffvalue).FirstOrDefault();
                        todeletevalue.Status = (int)DataStatus.Deleted;
                        todeletevalue.UpdateDate = DateTime.Now;
                        _prodpropertyvalRepo.Update(todeletevalue);
                    }
                    foreach(var diffvalue in newValue.Except(existValue))
                    {
                        _prodpropertyvalRepo.Insert(new ProductPropertyValueEntity(){
                             CreateDate = DateTime.Now,
                              UpdateDate = DateTime.Now,
                               Status =(int)DataStatus.Normal,
                                ValueDesc = diffvalue,
                                 PropertyId = propertyEntity.Id
                        });
                    }
                }
                ts.Complete();

            }
           
            return RedirectToAction("list");
        }
        public ActionResult Create(FormCollection formCollection, ProductPropertyViewModel vo)
        {
            if (!ModelState.IsValid)
            {
                return View(vo);
            }
            var propertyExist = _prodpropertyRepo.Get(t => t.ProductId == vo.ProductId && t.Status != (int)DataStatus.Deleted).Any();
            if (propertyExist)
            {
                ModelState.AddModelError("", "商品已经设置属性,使用修改功能来更新!");
                return View(vo);
            }
            using (var ts = new TransactionScope())
            {
                string propertyflag = null;
                ProductPropertyEntity newProperty = null;
                foreach (var pv in vo.Values.OrderBy(v => v.PropertyDesc))
                {
                    if (propertyflag != pv.PropertyDesc)
                    {
                        propertyflag = pv.PropertyDesc;
                        newProperty = _prodpropertyRepo.Insert(new ProductPropertyEntity()
                        {
                            ProductId = vo.ProductId,
                            PropertyDesc = pv.PropertyDesc,
                            Status = (int)DataStatus.Normal,
                            SortOrder = 0,
                            UpdateDate = DateTime.Now,
                            UpdateUser = CurrentUser.CustomerId
                        });
                    }
                    _prodpropertyvalRepo.Insert(new ProductPropertyValueEntity()
                    {
                        CreateDate = DateTime.Now,
                        PropertyId = newProperty.Id,
                        Status = (int)DataStatus.Normal,
                        UpdateDate = DateTime.Now,
                        ValueDesc = pv.ValueDesc

                    });

                }
                ts.Complete();
            }

            return RedirectToAction("Edit", new { id = vo.ProductId });

        }