问题 ASP.NET Web API Unity TransientLifetimeManager如何配置Dbcontext?

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
你好,

我正在使用工作单元,通用仓库和Unity作为DI。我的问题是TransientLifetimeManager无法处置Dbcontext,所以我必须以某种方式进行。您能检查我的代码并为我提供帮助吗?我找不到处理方法。

这是我的控制器:
C#:
namespace Game.Controllers
{
    [System.Web.Http.RoutePrefix("api/v2/game")]
    public class GameController : ApiController
    {
        private readonly IGameServices _gameServices;
     

        #region Public Constructor

        /// <summary>
        /// Public constructor to initialize game service instance
        /// </summary>
        public GameController(IGameServices gameServices)
        {
            _gameServices = gameServices;
        }

       
        #endregion


        // POST: api/Game
        //[RequireHttps] For Prod Only

        [HttpPost, Route("purchase")]
        public async Task<IHttpActionResult> PurchaseGame(RequestDto game)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            //Call Services
            var gameConfirmResponse = await _gameServices.GamePurchase(game);
            switch (gameConfirmResponse.StatusCode)
            {
                case HttpStatusCode.NotFound:
                {
                    return NotFound();
                }
                case HttpStatusCode.InternalServerError:
                {
                    return InternalServerError();
                }
                case HttpStatusCode.OK:
                {
                    if (gameConfirmResponse.Content == null)
                    {
                        return new System.Web.Http.Results.ResponseMessageResult(
                            Request.CreateErrorResponse((HttpStatusCode) 222, new HttpError("No Results Found")));
                    }

                    var responseStream = await gameConfirmResponse.Content.ReadAsStringAsync();

                    var resultResponse = JsonConvert.DeserializeObject<GameConfirmResponse>(responseStream);
                    if (resultResponse.coupons == null)
                    {
                        return new System.Web.Http.Results.ResponseMessageResult(
                            Request.CreateErrorResponse((HttpStatusCode) 222,
                                new HttpError("No Coupons Available for this Game")));
                    }

                    //Transform GameConfirmResponse into DTO for returning result
                    var config = new MapperConfiguration(cfg =>
                    {
                        cfg.CreateMap<GameConfirmResponse, GameConfirmResponseDto>();
                        cfg.CreateMap<Coupon, CouponDto>();
                    });
                    var iMapper = config.CreateMapper();
                    var resultDto = iMapper.Map<GameConfirmResponse, GameConfirmResponseDto>(resultResponse);
                    return Ok(resultDto);
                }
                case HttpStatusCode.Unauthorized:
                {
                    return Unauthorized();
                }
                case HttpStatusCode.RequestTimeout:
                {
                    return InternalServerError();
                }
            }

            return Ok(gameConfirmResponse);
        }

       

        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                ???
            }
            base.Dispose(disposing);
        }
    }
}

这是我的服务:
C#:
namespace BusinessService
{
    public class GameServices : IGameServices
    {
        private readonly UnitOfWork _unitOfWork;

        /// <summary>
        /// Public constructor.
        /// </summary>
        public GameServices(UnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
       
        /// <summary>
        /// Creates a product
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public async Task<HttpResponseMessage> GamePurchase(RequestDto requestDto)
        {
            HttpResponseMessage response = null;

            response = await CallGameNew(requestDto) ?? await CallRazerService(requestDto);

            return response;
        }

      

        private async Task<HttpResponseMessage> CallRazerService(RequestDto requestDto)
        {
            HttpResponseMessage response = null;

            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
               


                #region Call Razer initiate/confirm

                //Call Razer for initiation
                response = await Utilities.CallRazer(gameRequest, "purchaseinitiation");

                //Read response
                var htmlResponse = await response.Content.ReadAsStringAsync();
                var gameResponse = JsonConvert.DeserializeObject<GameResponse>(htmlResponse);

                //Adding initiation response into database
                _unitOfWork.GameResponseRepository.Insert(gameResponse);

                if (gameResponse.initiationResultCode == "00")
                {
                    gameRequestDto = iMapper.Map<GameRequest, GameRequestDto>(gameRequest);
                    gameRequestDto.validatedToken = gameResponse.validatedToken;
                    //Create signature
                    var gameConfirmRequest = Utilities.CreateSignature(gameRequestDto, RequestType.Confirm);

                    //Transform DTO into GameRequest for calling Razer Initiate
                    var gameConfirmRequests = iMapper.Map<GameRequest, GameConfirmRequest>(gameConfirmRequest);

                    //Add confirm request into database
                    _unitOfWork.GameConfirmRequestRepository.Insert(gameConfirmRequests);

                    //Call Razer for confirm
                    response = await Utilities.CallRazer(gameConfirmRequest, "purchaseconfirmation");

                    //Read response
                    htmlResponse = await response.Content.ReadAsStringAsync();
                    var gameConfirmResponse = JsonConvert.DeserializeObject<GameConfirmResponse>(htmlResponse);

                    //Set service
                    gameConfirmResponse.service = "RAZER";
                    //Add confirm response into database
                    _unitOfWork.GameConfirmResponseRepository.Insert(gameConfirmResponse);
                }

                #endregion

                await _unitOfWork.SaveAsync();
                scope.Complete();
            }

            return response;
        }


        }

    }
}

这是UOW:
C#:
namespace DataModels
{
    public class UnitOfWork : IDisposable
    {
        private readonly GameContext _context;
        private readonly GenericRepository<GameRequest> gameRequestRepository;
      

        public UnitOfWork(GameContext context)
        {
            _context = context;
        }

        public GenericRepository<GameRequest> GameRepository
        {
            get
            {
                return this.gameRequestRepository ?? new GenericRepository<GameRequest>(_context);
            }
        }
      

        public void Save()
        {
            _context.SaveChanges();
        }

        public async Task SaveAsync()
        {
            await _context.SaveChangesAsync();
        }

        private bool disposed = false;

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            this.disposed = true;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    }
}

这是Unity配置:
C#:
namespace Game
{
    /// <summary>
    /// Specifies the Unity configuration for the main container.
    /// </summary>
    public static class UnityConfig
    {
        #region Unity Container
        private static Lazy<IUnityContainer> container =
          new Lazy<IUnityContainer>(() =>
          {
              var container = new UnityContainer();
              RegisterTypes(container);
              return container;
          });

        /// <summary>
        /// Configured Unity Container.
        /// </summary>
        public static IUnityContainer Container => container.Value;
        #endregion

       
        public static void RegisterTypes(IUnityContainer container)
        {
            // Default empty Time manager!
            container.RegisterType<IGameServices, GameServices>().RegisterType<UnitOfWork>(new TransientLifetimeManager());
            container.RegisterType<IUserValidate, UserValidate>(new TransientLifetimeManager());
           
        }
    }
}
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,522
地点
弗吉尼亚州切萨皮克
编程经验
10+
WTF?!?!?我刚刚读对了吗?
C#:
namespace DataModels
{
    public class UnitOfWork : IDisposable
    {
        private readonly GameContext _context;

        :

        public UnitOfWork(GameContext context)
        {
            _context = context;
        }

        :

        protected virtual void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing)
                {
                    _context.Dispose();
                }
            }
            this.disposed = true;
        }
    }
}

通常,当使用依赖项注入时,接收依赖项来处理依赖项的不是类的责任。

为什么?因为您破坏了封装。现在,该类对外部环境足够了解,可以知道可以安全地删除传递给它的内容。

如果以后再实例化其中两个UnitOfWork对象,但只有一个GameContext怎么办?您如何告诉两个工作单元之一不处理您提供的游戏环境?现在,您再次打破封装的Demeter法则,因为现在外部环境了解对象的内部工作原理。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,522
地点
弗吉尼亚州切萨皮克
编程经验
10+
WTF?!?!?!如果不打算使用像Unity这样的控制工具,那有什么意义呢?
C#:
        public GenericRepository<GameRequest> GameRepository
        {
            get
            {
                return this.gameRequestRepository ?? new GenericRepository<GameRequest>(_context);
            }
        }
}
当将通用存储库注入任何需要的对象时,为什么要在此处实例化GenericRepository?

关于此相同代码的另一种说法是,为什么返回通用仓库(新仓库或其他仓库)是工作单元的工作? WTF?!?!?!?!
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,522
地点
弗吉尼亚州切萨皮克
编程经验
10+
无论如何,要回答有关如何使DI处理数据库上下文的原始问题,答案是您在DI中注册了数据库上下文类型。 DI的工作是照顾对象实例的生命周期,并确保将实例注入到将它们作为依赖项的类型中。

我有一种独特的感觉,您已经接受了诸如工作单元,存储库和依赖注入之类的流行词,并试图将它们全部融合到该项目中,但是还没有花时间学习如何独立于它们使用它们。彼此。现在,当您将它们全部放在一起时,您的学习曲线非常陡峭,而实际上并没有很好地理解为什么要使用它们。例如,您上面的Unit of Work类似乎是游戏上下文中的一薄层,并没有真正增加任何实际价值。
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
是的,您是对的,这是我第一次尝试实现Web API。我读了很多文章,然后迷路了很多次。有什么建议(尤其是示例)来改进代码吗?

无论如何,要回答有关如何使DI处理数据库上下文的原始问题,答案是您在DI中注册了数据库上下文类型。 DI的工作是照顾对象实例的生命周期,并确保将实例注入到将它们作为依赖项的类型中。

我读到瞬态生存期不会自动处理dbcontext,因此我应该以某种方式进行处理。除了您上面的评论,这是我目前的主要问题。
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
如果将处置添加到服务中,是否可以解决我的问题?你怎么认为?

C#:
namespace BusinessService
{
    public class GameServices : IGameServices
    {
        private readonly UnitOfWork _unitOfWork;

        /// <summary>
        /// Public constructor.
        /// </summary>
        public GameServices(UnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
        

        /// <summary>
        /// Creates a product
        /// </summary>
        /// <param name="requestDto"></param>
        /// <returns></returns>
        public async Task<HttpResponseMessage> GamePurchase(RequestDto requestDto)
        {
            HttpResponseMessage response = null;

            response = await CallGameNew(requestDto) ?? await CallRazerService(requestDto);

            return response;
        }

      

        private async Task<HttpResponseMessage> CallGameNew(RequestDto requestDto)
        {
            HttpResponseMessage response = null;
            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                //Transform DTO into GameRequest for calling Game Initiate
                var config = new MapperConfiguration(cfg =>
                {
                    cfg.CreateMap<RequestDto, GameRequest>();
                    cfg.CreateMap<GameRequest, GameConfirmRequest>();
                    cfg.CreateMap<GameBank, GameConfirmResponse>();
                    cfg.CreateMap<GameBankPin, Coupon>();
                    cfg.CreateMap<GameRequest, GameRequestDto>();
                });
                var iMapper = config.CreateMapper();
                var gameRequest = iMapper.Map<RequestDto, GameRequest>(requestDto);
                //Unique reference ID
                gameRequest.referenceId = Guid.NewGuid();
                
                var gameRequestDto = iMapper.Map<GameRequest, GameRequestDto>(gameRequest);
                //Create signature
                gameRequest = Utilities.CreateSignature(gameRequestDto, RequestType.Initiate);

                //Set service
                gameRequest.service = "OUR";

                //Add initiation request into database
                _unitOfWork.GameRepository.Insert(gameRequest);

                //Query GameBank database
                var gameBankResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g =>
                    g.productCode == requestDto.productCode && g.referenceId == Guid.Empty);

                
                if (gameBankResult.Count() >= requestDto.quantity)
                {
                    var k = requestDto.quantity - 1;
                    for (var i = k; i >= 0; --i)
                    {
                        gameBankResult[i].referenceId = gameRequest.referenceId;
                        gameBankResult[i].requestDateTime = DateTime.Now;
                        gameBankResult[i].responseDateTime = DateTime.Now;
                        
                    }

                    //Update GameBank
                    _unitOfWork.GameBankRepository.Update(gameBankResult[k]);

                    var gameBankConfirmResponse =
                        iMapper.Map<IList<GameBank>, IList<GameConfirmResponse>>(gameBankResult);

                  
                    if (requestDto.quantity == 1)
                    {
                        gameBankConfirmResponse[k].purchaseStatusDate = DateTime.Now;

                        var resultResponse = JsonConvert.SerializeObject(gameBankConfirmResponse[k],
                            Formatting.Indented,
                            new JsonSerializerSettings()
                            {
                                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                            });
                        response = new HttpResponseMessage
                        {
                            StatusCode = System.Net.HttpStatusCode.OK,
                            Content = new StringContent(resultResponse, System.Text.Encoding.UTF8, "application/json"),
                        };
                        //Set service
                        gameBankConfirmResponse[k].service = "OUR";
                        _unitOfWork.GameConfirmResponseRepository.Insert(gameBankConfirmResponse[k]);
                    }
                    else if (requestDto.quantity > 1)
                    {
                        var gameResult = new GameConfirmResponse
                        {
                            coupons = new List<Coupon>()
                        };
                        var price = 0.0;
                        var quantity = 0;

                        foreach (var item in gameBankResult)
                        {
                            price = price + item.unitPrice;
                            quantity = quantity + 1;
                            foreach (var coupons in item.coupons)
                            {
                                var gameCouponResult = new Coupon()
                                {
                                    expiryDate = coupons.expiryDate,
                                    Pin = coupons.Pin,
                                    Serial = coupons.Serial
                                };
                                //Add coupon values
                                gameResult.coupons.Add(gameCouponResult);
                            }

                        }

                        //Set summed/counted values
                        gameResult.referenceId = gameBankResult[0].referenceId;
                        gameResult.productCode = gameBankResult[0].productCode;
                        gameResult.quantity = quantity;
                        gameResult.currency = gameBankResult[0].currency;
                        gameResult.unitPrice = gameBankResult[0].unitPrice;
                        gameResult.totalPrice = price;
                        gameResult.productDescription = gameBankResult[0].productDescription;
                        gameResult.purchaseStatusDate = DateTime.Now;
                        gameResult.totalPayablePrice = price;
                        //Set service
                        gameRequest.service = "OUR";

                        //var gameBankConfirmResponse = iMapper.Map<GameBank, GameConfirmResponse>(gameResult);
                        //Add confirm response into database
                        _unitOfWork.GameConfirmResponseRepository.Insert(gameResult);
                        var resultResponse = JsonConvert.SerializeObject(
                            gameResult, Formatting.Indented,
                            new JsonSerializerSettings()
                            {
                                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                            });
                        response = new HttpResponseMessage
                        {
                            StatusCode = System.Net.HttpStatusCode.OK,
                            Content = new StringContent(
                                resultResponse, System.Text.Encoding.UTF8,
                                "application/json"),
                        };
                    }
                    
                }
                
                await _unitOfWork.SaveAsync();

                scope.Complete();
            }

            return response;
        }

    
...

        public void Dispose()
        {
            _unitOfWork.Dispose();
        }

    }
}
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
如果将处置添加到服务中,是否可以解决我的问题?
您的课程继承了Idisposable吗?

如果要制作可重用的代码,则需要用可重用的代码实现可重用的方法,这就是为什么我在早期就告诉过using块的使用的原因。当using语句完成执行继承了Idisposable的对象后,它将运行自身处理方法(执行后)以清理其资源已使用的对象。

我应该以某种方式照顾它。除了您上面的评论,这是我目前的主要问题。
我认为您的优先顺序是错误的。
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
如果要制作可重用的代码,则需要用可重用的代码实现可重用的方法,这就是为什么我在早期就告诉过using块的使用的原因。当using语句完成执行继承了Idisposable的对象后,它将运行自身处理方法(执行后)以清理其资源已使用的对象。

您完全正确,但是在我的情况下,我该如何使用使用?你能告诉我吗?您检查过我的源代码了吗?

是的,它现在继承自IDisposable。
C#:
namespace BusinessService
{
    public class GameServices : IGameServices, IDisposable
    {
        private readonly UnitOfWork _unitOfWork;

        /// <summary>
        /// Public constructor.
        /// </summary>
        public GameServices(UnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }
        ...
        //Some code here

        public void Dispose()
        {
            _unitOfWork.Dispose();
            
        }

    }
}
 
Last edited:

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
严格伪,不被视为::

C#:
namespace TestCSharpApp
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            FooClass FC = new FooClass();
            using (FC)
            {
                Console.WriteLine(FC.foo);
            }
        }
    }
    public class FooClass : IDisposable
    {
        public int foo;
        public void Dispose()
        {
            Console.WriteLine(0);
        }
    }
}
在第12行上放置一个断点,然后按F11并完成使用周期,您将注意到FooClass dispose方法将触发。因为我在第8行上实例化了该类的新实例,所以我想以这样的方式使用它:我对它的处理方式,并且在循环完成使用后,在其中内部将正确且一致地公开。如果您还不知道,使用块是自处置的,因此我个人鼓励在适用的每个机会中使用它们。顺便说一句,我敢打赌这可能是为什么您在福彩12选5走势图池中获得所有那些阻塞的福彩12选5走势图的原因,但是由于我们看不到您的所有代码,所以我只是在推测。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
老实说,我会在您的代码中进行很多更改,很抱歉,但是我没有多余的时间坐在这里为您做代码。
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
顺便说一句,我敢打赌这可能是为什么您在福彩12选5走势图池中获得所有那些阻塞的福彩12选5走势图的原因,但是由于我们看不到您的所有代码,所以我只是在推测。

来吧,你的例子很简单。我多次发布代码。关键是,您真的想提供帮助吗?

我认为根据您的样本,这基本上可以工作。
C#:
private async Task<HttpResponseMessage> CallGameNew(RequestDto requestDto)
        {
            HttpResponseMessage response = null;
            using (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                using(_unitOfWork)
                {
               
                    //some code here

                //Add initiation request into database
                _unitOfWork.GameRepository.Insert(gameRequest);

                //Query GameBank database
                var gameBankResult = await _unitOfWork.GameBankRepository.GetGamesAsync(g =>
                    g.productCode == requestDto.productCode && g.referenceId == Guid.Empty);

             
                    //some code there
                   
                        //Add confirm response into database
                        _unitOfWork.GameConfirmResponseRepository.Insert(gameResult);
                       
                    }
                   
                }
               
                await _unitOfWork.SaveAsync();
   }

                scope.Complete();
            }

            return response;
        }
 
Last edited:

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
我的示例可能是基本示例,但它是您所要求的完美示例: how could I use using? Can you please tell me?

如果您不愿意查看自己的代码以查看要实例化IDisposable对象以应用必要更改的位置,那么我也不能。如果这看起来很严厉,我感到抱歉。我不是来给你喂汤的。我目前正在从事自己的项目,包括个人和客户工作。我或任何其他人在这些论坛上所做的事情都是完全强制性的,并取决于他们可以或希望贡献自己的时间。我没有时间,因为我必须编写Linq / SQL查询以及有关URI重写的整个类,因此您认为哪个优先?

我还应该指出,您正在与吉米·塔赫·法兹接壤,后者对此感到皱眉。当然,我们想为您提供帮助,但是您也需要表现出承诺。从外观上看,您似乎没有采取跳伞者在下巴上说的任何话。在此主题或其他主题中。负责
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
当我将处置添加到GameService中时(在第8个线程中),当我尝试在10个加速时间下对350个用户进行负载测试时,出现了此错误。实际上有一个改进,在更改代码之前,我可以成功地对少于150个用户进行负载测试。

我用了"using"对于所有交易。
C#:
使用 (var scope = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {

//code
}


System.Transactions.TransactionException:该操作对于事务状态无效。 --->System.TimeoutException:事务超时。基础提供程序在打开时失败。


任何想法如何解决这个问题?
 
Last edited:

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
System.TimeoutException:事务超时。基础提供程序在打开时失败。
似乎是您的福彩12选5走势图未关闭的问题。我的理论是您正在使用多个福彩12选5走势图。检查显式打开的福彩12选5走势图,并在事务执行后检查福彩12选5走势图是否也在关闭。

通常允许每个用户一个福彩12选5走势图,并且在该福彩12选5走势图内部,用户可以在给定范围内执行多个查询。如果打开多个福彩12选5走势图,则第二个福彩12选5走势图将阻止查询运行。您只能在打开第一个福彩12选5走势图的实例上运行事务。如果要创建福彩12选5走势图的新实例,则不要。每次都使用相同的实例。除非您知道上一个福彩12选5走势图实例已被正确丢弃,否则切勿创建多个福彩12选5走势图实例。

我希望您阅读以下问题以及有关的可接受答案 堆栈溢出。我不喜欢经常链接到该站点,因为当错误信息不经常正确时,会误入许多错误信息作为可接受的答案。不过,在这种情况下,我相信它会为您提供帮助。

如果使用的是IIS Express,请右键单击任务栏图标,然后停止站点。这将释放或应该释放您的项目可能阻塞的福彩12选5走势图。
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
我会尝试的,希望它能起作用。

TransactionScope和多线程

更新: 查看文档后 这里,我看到Database.BeginTransaction()是首选的EF调用。但是,这假设我的所有更改都将在同一上下文中发生,而不会发生。除了创建虚拟上下文并传递事务外,我认为这不能解决我的问题。

我不明白他为解决他的问题做了什么。
"更新: 查看文档后 这里,我看到Database.BeginTransaction()是首选的EF调用。但是,这假设我的所有更改都将在同一上下文中发生,而不会发生。除了创建虚拟上下文并传递事务外,我认为这不能解决我的问题。"

或者他是在谈论如下使用Dbcontext而不是事务?
C#:
使用 (_unitOfWork)
            {
                //some code here

                //Add initiation request into database
                _unitOfWork.GameRepository.Insert(gameRequest);

                //some code here
                    //Add confirm request into database
                    _unitOfWork.GameConfirmRequestRepository.Insert(gameConfirmRequests);

                  //some code here
                    //Add confirm response into database
                    _unitOfWork.GameConfirmResponseRepository.Insert(gameConfirmResponse);
                }

                #endregion

                await _unitOfWork.SaveAsync();
              
            }
 
Last edited:

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
这是一个可怕的想法。将多线程引入其中​​会带来不必要的麻烦。

看来您很无视建议。我上面发布的两个福彩12选5走势图的问题又如何呢?您将再次遇到相同的问题。

EF适用于懒惰的人,不想因linq / Sql而烦恼。为什么不只是学习术语呢?

我看到Database.BeginTransaction()是首选的EF调用。
这很重要,因为您的福彩12选5走势图(而不是事务)的代码使您的福彩12选5走势图池阻塞。我们将再次转圈。您需要更改代码以适应对所有查询使用一个福彩12选5走势图。

在您对之前所做的更改以及不再忽略建议之前,我无法提供进一步的帮助。

编辑:错别字
 
Last edited:

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
好的,我将在运行操作方法时检查数据库以查看是否存在多个福彩12选5走势图。如果有,我将尝试更改为代码。谢谢你。
 

羊皮

退休程序员
工作人员
已加入
2018年9月5日
留言内容
1,926
地点
英国
编程经验
10+
这更多是基于我的想法,您的进步以及我对此的有限经验而得出的观点。您可能要先喝杯茶!

在MySQL服务器中,您可以检查您的福彩12选5走势图过程的information_schema,但是在SQL Server中,我认为您必须通过命令行来完成。您应该检查代码,而不是数据库。从您收到的最后一个错误我们知道,现在您的福彩12选5走势图在某个时候没有关闭。在第15章中,我强烈建议不要使用第一个链接,因为我看不到这样做会如何完成。我有一个与EF合作的同事,但不是我,我个人从来都不喜欢它,我也不认为自己是一个过分自信的EF用户,但我足够了解。主要是看他的任务,当他受命在我们公司使用它时。

使用using块并封装福彩12选5走势图并在其中执行命令。这就是我在想的...我想您应该创建一个SQL管理类,该类将为您处理所有福彩12选5走势图并绕过EFs自动福彩12选5走势图管理。这样,您可以显式打开和关闭需要执行命令的福彩12选5走势图,并且可以处理自己的福彩12选5走势图并管理其福彩12选5走势图状态。除非明确打开/关闭它们,否则您无法使用EF进行操作。 (至少我不知道。)我读过人们创建了我称之为SQL管理的工厂类。当需要执行命令时,EF无需为您管理福彩12选5走势图,而这成为了SQL工厂类负责处理的责任,因此,如果您考虑考虑这一点,请确保它在以下情况下达到要求它涉及可靠性和可重用性。

根据 布伦特·奥扎尔,EF不会干扰用户明确打开的福彩12选5走势图。鉴于我相信EF的旧版本也可以将其关闭。我不觉得这是什么痛苦,但EF6不再是问题。虽然这是我第一次真正有足够的时间浏览您的第一篇文章,并正确确定要指出的内容。我建议重新开始。我不会重写任何东西,放弃它。我一直在考虑您的选择,尽管我知道放弃EF可能对您也不利。我确实认为这将在故障排除,性能,学习和编写更可靠的代码方面减轻您的痛苦。我实际上找到了您的一些代码。令人难以置信。

我了解您为什么像大多数开发人员一样使用EF,它将或将要减轻负担并加快开发速度。是的,您得到了快速的发展,但最终却要权衡性能,这主要是因为在EF中如何解析信息和数据,而我个人不应该对此进行权衡。 (表现)。并且由于您要进行过多的压力测试(比默认值高三倍),因此我假设您希望您的应用程序很忙,如果是这样的话;您真的真的最能实施EF吗?

详细说明我在上面的最后一点。如果您期望数据库的大小会增加,或者如果您需要其他字段,列,表等,将会发生什么情况。这对于以后的您来说将是一个巨大的问题,(尤其是如果您决定从EF迁移到另一个手动集成),因为与linq的集成将变得非常复杂,这是我会避免的事情。但是,如果您确定您的应用程序数据库不需要更改或无需扩展产品线,那么您不必担心。

我认为,如果您在八个左右的主题中实施了许多建议,您将获得更多反馈。正如Skydiver在其他地方已经说过的那样,请在确保性能之前让您的应用程序执行无缺陷。我也很好奇是否应该考虑我的上述言论,或者如果有人打算实施自己的SQL工厂类来管理福彩12选5走势图,我的建议是否会从使用Unity / EF的目的中消失?我之所以提出建议,是因为我阅读了许多遭受相同问题困扰的用户的报告。

您需要考虑的事情 @raysefo.
 

Raysefo

知名会员
已加入
2019年2月22日
留言内容
192
编程经验
10+
我对你们有个好消息。我对1000个用户和10秒的启动时间进行了负载测试,没有错误 :) 我只是从代码中删除了交易范围。
 
最佳 底部