예제 #1
0
        /// <summary>
        /// Configure context options<br/>
        /// 配置上下文选项<br/>
        /// </summary>
        /// <param name="optionsBuilder">Options builder</param>
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var pathConfig = Application.Ioc.Resolve <LocalPathConfig>();

            if (string.Compare(DatabaseName, "MSSQL", true) == 0)
            {
                optionsBuilder.UseSqlServer(
                    ConnectionString, option => option.UseRowNumberForPaging());
            }
            else if (string.Compare(DatabaseName, "SQLite", true) == 0)
            {
                optionsBuilder.UseSqlite(
                    ConnectionString.Replace("{{App_Data}}", pathConfig.AppDataDirectory));
            }
            else if (string.Compare(DatabaseName, "MySQL", true) == 0)
            {
                optionsBuilder.UseMySql(ConnectionString);
            }
            else if (string.Compare(DatabaseName, "PostgreSQL", true) == 0)
            {
                optionsBuilder.UseNpgsql(ConnectionString);
            }
            else if (string.Compare(DatabaseName, "InMemory", true) == 0)
            {
                optionsBuilder.UseInMemoryDatabase(
                    string.IsNullOrEmpty(ConnectionString) ?
                    GuidUtils.SequentialGuid(DateTime.UtcNow).ToString() : ConnectionString);
            }
            else
            {
                throw new ArgumentException($"unsupported database type {Database}");
            }
            // EF 2.0 make some warnings as error, just ignore them
            optionsBuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.IncludeIgnoredWarning));
        }
예제 #2
0
        public void SequentialGuid()
        {
            var a = GuidUtils.SequentialGuid(new DateTime(2016, 8, 8));
            var b = GuidUtils.SequentialGuid(new DateTime(2016, 8, 9));

            Assert.IsTrue(a != Guid.Empty);
            Assert.IsTrue(b != Guid.Empty);
            Assert.IsTrueWith(string.Compare(a.ToString(), b.ToString()) < 0, new { a, b });
        }
예제 #3
0
 /// <summary>
 /// 自动设置Guid主键值
 /// </summary>
 void IEntityOperationFilter.FilterSave <TEntity, TPrimaryKey>(TEntity entity)
 {
     if (typeof(TPrimaryKey) == typeof(Guid))
     {
         var eg = (IEntity <Guid>)entity;
         if (eg.Id == Guid.Empty)
         {
             // 主键是空时自动生成主键
             eg.Id = GuidUtils.SequentialGuid(DateTime.UtcNow);
         }
     }
 }
예제 #4
0
        /// <summary>
        /// Configure context options<br/>
        /// 配置上下文选项<br/>
        /// </summary>
        /// <param name="optionsBuilder">Options builder</param>
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            var pathConfig = Application.Ioc.Resolve <LocalPathConfig>();

            if (string.Compare(DatabaseName, "MSSQL", true, CultureInfo.InvariantCulture) == 0)
            {
                optionsBuilder.UseSqlServer(
                    ConnectionString, option => option.UseRowNumberForPaging());
            }
            else if (string.Compare(DatabaseName, "SQLite", true, CultureInfo.InvariantCulture) == 0)
            {
                optionsBuilder.UseSqlite(
                    ConnectionString.Replace("{{App_Data}}", pathConfig.AppDataDirectory));
            }
            else if (string.Compare(DatabaseName, "MySQL", true, CultureInfo.InvariantCulture) == 0)
            {
                optionsBuilder.UseMySql(ConnectionString);
            }
            else if (string.Compare(DatabaseName, "PostgreSQL", true, CultureInfo.InvariantCulture) == 0)
            {
                optionsBuilder.UseNpgsql(ConnectionString);
            }
            else if (string.Compare(DatabaseName, "InMemory", true, CultureInfo.InvariantCulture) == 0)
            {
                optionsBuilder.UseInMemoryDatabase(
                    string.IsNullOrEmpty(ConnectionString) ?
                    GuidUtils.SequentialGuid(DateTime.UtcNow).ToString() : ConnectionString);
            }
            else
            {
                throw new ArgumentException($"unsupported database type {Database}");
            }
            // EF 2.0 make some warnings as error, just ignore them
            // EF 3.0 obsolete IncludeIgnoredWarning without any comment and description, wtf?
            #pragma warning disable CS0612
            optionsBuilder.ConfigureWarnings(w => w.Ignore(CoreEventId.IncludeIgnoredWarning));
            #pragma warning restore CS0612
            // Allow logging sql parameters
            optionsBuilder.EnableSensitiveDataLogging();
            // Enable lazy loading (exclude .NET Core 3.0)
            // On .NET Core 3.0 you will see this error:
            // A non-collectible assembly may not reference a collectible assembly
            // See this issue:
            // https://github.com/aspnet/EntityFrameworkCore/issues/18272
            if (!Application.Unloadable)
            {
                optionsBuilder.UseLazyLoadingProxies();
            }
        }
예제 #5
0
        /// <summary>
        /// 转换到数据库使用的集合
        /// </summary>
        /// <param name="values">编辑后的商品属性对应的属性值列表</param>
        /// <param name="property">商品属性</param>
        /// <returns></returns>
        public static ISet <ProductPropertyValue> ToDatabaseSet(
            this IList <ProductPropertyValueForEdit> values, ProductProperty property)
        {
            if (values == null)
            {
                return(new HashSet <ProductPropertyValue>());
            }
            var set       = property.PropertyValues ?? new HashSet <ProductPropertyValue>();
            var addValues = new List <ProductPropertyValue>();
            var now       = DateTime.UtcNow;

            for (int i = 0; i < values.Count; ++i)
            {
                var value = values[i];
                if (value.Id == null)
                {
                    // 添加属性值(临时)
                    addValues.Add(new ProductPropertyValue()
                    {
                        Id           = GuidUtils.SequentialGuid(now),
                        Name         = value.Name,
                        Property     = property,
                        DisplayOrder = i,
                        CreateTime   = now,
                        UpdateTime   = now,
                        Remark       = value.Remark
                    });
                }
                else
                {
                    // 更新属性值
                    var updateValue = set.First(p => p.Id == value.Id);
                    updateValue.Name         = value.Name;
                    updateValue.DisplayOrder = i;
                    updateValue.UpdateTime   = now;
                    updateValue.Remark       = value.Remark;
                }
            }
            // 删除属性值
            var aliveIds     = new HashSet <Guid>(values.Where(v => v.Id != null).Select(v => v.Id.Value));
            var deleteValues = set.Where(p => !aliveIds.Contains(p.Id)).ToList();

            deleteValues.ForEach(v => set.Remove(v));
            // 添加属性值
            addValues.ForEach(v => set.Add(v));
            return(set);
        }
예제 #6
0
        /// <summary>
        /// If an entity have a integer or guid primary key, and it's empty,<br/>
        /// then generate a new primary key for it.<br/>
        /// Return the final primary key.<br/>
        /// 如果实体有一个数值或者guid主键, 并且主键为空<br/>
        /// 则生成一个新的主键<br/>
        /// 返回最终的主键<br/>
        /// </summary>
        public object EnsurePrimaryKey <T>(T entity)
        {
            var mapping    = Mappings[typeof(T)];
            var primaryKey = GetPrimaryKey(entity);

            if ((primaryKey is int || primaryKey is long) && ((long)primaryKey) <= 0)
            {
                lock (PrimaryKeySequenceLock) {
                    primaryKey = PrimaryKeySequence.GetOrAdd(typeof(T), 0) + 1;
                    PrimaryKeySequence[typeof(T)] = (long)primaryKey;
                }
                mapping.IdMember.FastSetValue(entity, primaryKey);
            }
            else if (primaryKey is Guid && (Guid)primaryKey == Guid.Empty)
            {
                primaryKey = GuidUtils.SequentialGuid(DateTime.UtcNow);
                mapping.IdMember.FastSetValue(entity, primaryKey);
            }
            return(primaryKey);
        }
예제 #7
0
        /// <summary>
        /// 按卖家分别创建订单
        /// </summary>
        protected virtual void CreateOrdersBySellers()
        {
            var orderManager             = Application.Ioc.Resolve <SellerOrderManager>();
            var userManager              = Application.Ioc.Resolve <UserManager>();
            var productManager           = Application.Ioc.Resolve <ProductManager>();
            var buyerOrderManager        = Application.Ioc.Resolve <BuyerOrderManager>();
            var transactionManager       = Application.Ioc.Resolve <PaymentTransactionManager>();
            var products                 = new Dictionary <Guid, Product>();
            var groupedProductParameters = Parameters.OrderProductParametersList.Select(p => new {
                productParameters = p,
                product           = products.GetOrCreate(p.ProductId, () => productManager.Get(p.ProductId))
            }).GroupBy(p => p.product.Seller?.Id).ToList();             // { 卖家: [ (参数, 商品) ] }
            var now = DateTime.UtcNow;

            foreach (var group in groupedProductParameters)
            {
                // 计算订单的价格
                // 支付手续费需要单独提取出来
                var orderPrice = orderManager.CalculateOrderPrice(
                    Parameters.CloneWith(group.Select(o => o.productParameters).ToList()));
                var paymentFee = orderPrice.Parts.FirstOrDefault(p => p.Type == "PaymentFee");
                orderPrice.Parts.Remove(paymentFee);
                // 生成卖家订单
                var sellerOrder = new SellerOrder()
                {
                    Buyer                       = Parameters.UserId == null ? null : userManager.Get(Parameters.UserId.Value),
                    Owner                       = (group.Key == null) ? null : userManager.Get(group.Key.Value),
                    State                       = OrderState.WaitingBuyerPay,
                    OrderParameters             = Parameters.OrderParameters,
                    TotalCost                   = orderPrice.Parts.Sum(),
                    Currency                    = orderPrice.Currency,
                    TotalCostCalcResult         = orderPrice,
                    OriginalTotalCostCalcResult = orderPrice,
                    StateTimes                  = new OrderStateTimes()
                    {
                        { OrderState.WaitingBuyerPay, now }
                    }
                };
                // 添加关联的订单商品
                // 这里会重新计算单价,但应该和之前的计算结果一样
                foreach (var obj in group)
                {
                    var unitPrice = orderManager.CalculateOrderProductUnitPrice(
                        Parameters.UserId, obj.productParameters);
                    var orderCount   = obj.productParameters.MatchParameters.GetOrderCount();
                    var properties   = obj.productParameters.MatchParameters.GetProperties();
                    var orderProduct = new OrderProduct()
                    {
                        Id                          = GuidUtils.SequentialGuid(now),
                        Order                       = sellerOrder,
                        Product                     = obj.product,
                        MatchParameters             = obj.productParameters.MatchParameters,
                        Count                       = orderCount,
                        UnitPrice                   = unitPrice.Parts.Sum(),
                        Currency                    = unitPrice.Currency,
                        UnitPriceCalcResult         = unitPrice,
                        OriginalUnitPriceCalcResult = unitPrice,
                        CreateTime                  = now,
                        UpdateTime                  = now
                    };
                    // 添加关联的属性
                    foreach (var productToPropertyValue in obj.product
                             .FindPropertyValuesFromPropertyParameters(properties))
                    {
                        orderProduct.PropertyValues.Add(new OrderProductToPropertyValue()
                        {
                            Id                = GuidUtils.SequentialGuid(now),
                            OrderProduct      = orderProduct,
                            Category          = obj.product.Category,
                            Property          = productToPropertyValue.Property,
                            PropertyValue     = productToPropertyValue.PropertyValue,
                            PropertyValueName = productToPropertyValue.PropertyValueName
                        });
                    }
                    sellerOrder.OrderProducts.Add(orderProduct);
                }
                // 添加关联的订单留言
                var comment = Parameters.OrderParameters.GetOrderComment();
                if (!string.IsNullOrEmpty(comment))
                {
                    sellerOrder.OrderComments.Add(new OrderComment()
                    {
                        Id         = GuidUtils.SequentialGuid(now),
                        Order      = sellerOrder,
                        Owner      = sellerOrder.Buyer,
                        Side       = OrderCommentSide.BuyerComment,
                        Contents   = comment,
                        CreateTime = now,
                        UpdateTime = now
                    });
                }
                // 生成订单编号
                sellerOrder.Serial = SerialGenerator.GenerateFor(sellerOrder);
                // 保存卖家订单
                orderManager.Save(ref sellerOrder);
                Result.CreatedSellerOrders.Add(sellerOrder);
                // 生成买家订单
                var buyerOrder = new BuyerOrder()
                {
                    Owner          = sellerOrder.Buyer,
                    SellerOrder    = sellerOrder,
                    BuyerSessionId = (sellerOrder.Buyer != null) ? null : (Guid?)Parameters.SessionId
                };
                // 保存买家订单
                buyerOrderManager.Save(ref buyerOrder);
                Result.CreatedBuyerOrders.Add(buyerOrder);
                // 创建订单交易
                // 因为目前只能使用后台的支付接口,所以收款人应该是null
                var paymentApiId = Parameters.OrderParameters.GetPaymentApiId();
                var transaction  = transactionManager.CreateTransaction(
                    OrderTransactionHandler.ConstType,
                    paymentApiId,
                    sellerOrder.TotalCost,
                    paymentFee?.Delta ?? 0,
                    sellerOrder.Currency,
                    sellerOrder.Buyer?.Id,
                    null,
                    sellerOrder.Id,
                    sellerOrder.Serial);
                Result.CreatedTransactions.Add(transaction);
            }
        }