问题 ASP.NET. Web API Unity TransientLifetimeManager如何处理DBContext?

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
你好,

我正在使用一个单位的工作,通用repo和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 Config:
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,855
地点
切萨皮克,va.
编程经验
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;
        }
    }
}

通常,在使用依赖注入时,它不是接收依赖性依赖依赖的类的责任。

为什么?因为你正在打破封装。该班级现在已经知道它在外面的环境中知道它可以安全地删除交给它的东西。

如果在后面的道路上,你实例化了两个这些单位对象,还有一个gameContext?您如何介绍两种工作单位之一,以便不处理您给出的游戏背景?现在,您再次破坏遗迹的遗迹,因为现在外界的外观知道对象的内部工作。
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,855
地点
切萨皮克,va.
编程经验
10+
WTF?!?!?!如果您不使用它,使用控制工具的反转的重点是什么?
C#:
        public GenericRepository<GameRequest> GameRepository
        {
            get
            {
                return this.gameRequestRepository ?? new GenericRepository<GameRequest>(_context);
            }
        }
}
为什么当应该将通用存储库注入到任何对象需要它的通用存储库时,在此处实例化泛译课程?

还有关于这个代码的另一个粘性,为什么它是工作单位的作业来返回通用存储库(新或以其他方式)? WTF?!?!?!?!
 

跳伞运动员

工作人员
加入
2019年4月6日
消息
2,855
地点
切萨皮克,va.
编程经验
10+
无论如何,要回答你的原始问题,你如何让你的di丢弃你的数据库上下文,答案是你用di注册数据库上下文类型。 DI的工作是要处理对象实例的生命周期,并确保该实例注入将它们作为依赖的类型。

我正在获得不同的感觉,你拍摄了像工作单位,存储库和依赖注入的流行语,并试图将它们全部粘合到这个项目中,但没有完全花时间学习如何独立使用它们彼此。现在你在一个非常陡峭的学习曲线上,同时扔掉它们,没有真正了解你将使用它们的原因。例如,上面的工作类单位似乎是游戏上下文周围的薄层,而不是真正添加任何实际值。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
是的,您是对的,这是我第一次尝试实现Web API。我读过文章,沿着道路混淆了很多次。任何建议(尤其是样本)以改进代码?

无论如何,要回答你的原始问题,你如何让你的di丢弃你的数据库上下文,答案是你用di注册数据库上下文类型。 DI的工作是要处理对象实例的生命周期,并确保该实例注入将它们作为依赖的类型。

我读到瞬态寿命不会自动处理DBContext,所以不知何故,我应该照顾它。这是我的主要问题,现在除了您的评论之外。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
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();
        }

    }
}
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
如果我添加进入服务,它是否解决了我的问题?
您的课程是否遗产是可IDisposable?

如果要进行可重用的代码,则需要使用可重用的代码来实现可重用的方法,这就是为什么我早期告诉您使用块的使用。当执行遗传IDisposable的对象时,将完成使用语句,它将自行处理方法本身(执行后)以清除其资源使用的对象。

不知怎的,我应该照顾它。这是我的主要问题,现在除了您的评论之外。
在我看来,你的优先事项是错误的。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
如果要进行可重用的代码,则需要使用可重用的代码来实现可重用的方法,这就是为什么我早期告诉您使用块的使用。当执行遗传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:

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
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行上实例化了类的新实例,所以我想用它来这样的方式,即我用它做什么,而在循环完成后,它将被正确且一致地暴露。如果您已经知道,使用块是自我处理的,我会亲自鼓励他们在适用的每个机会上使用它们。除了旁边,我打赌这很可能是为什么你把所有这些都在你的连接池中封锁连接,而是因为我们看不到你的所有代码,我只是枪杀。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
要诚实地,你的代码有很多变化,我会做出很多改变,我很抱歉,但我没有业余时间坐在这里为你这样做。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
除了旁边,我打赌这很可能是为什么你把所有这些都在你的连接池中封锁连接,而是因为我们看不到你的所有代码,我只是枪杀。

来吧,你的例子是基本的。我多次发布了我的代码。重点是,你真的想帮忙吗?

我认为根据您的样本,这主要可能有效。
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:

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
我的例子可能是基本的,但它是你所要求的内容的一个完美的例子: how could I use using? Can you please tell me?

如果您不能打扰查看您自己的代码,请查看您实例化Idisposable对象以应用必要的更改,也不是。如果似乎严厉,我很抱歉。我不是在这里勺子喂你。我目前正在研究自己的项目,都是个人和客户的工作。在这些论坛上我或其他人在这些论坛上是完全义务的,并根据他们的时间或希望为自己做出多大贡献的时间。我没有时间,因为我必须编写LINQ / SQL查询,以及一个整个类上的URI重写,所以你认为哪个优先?

我还应该指出,你在Gimi Tah Codez上接壤,这是令人沮丧的。当然,我们想要帮助您,但您也需要表现出承诺。从东西的外表,你似乎没有采取任何跳伞运动员在下巴上说的话;在此或您的其他主题中。负责。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
当我将处理添加到GamesService(在我的第8个线程中)时,我试图用350个用户使用10个斜坡的时间加载测试时出现此错误。实际上有一个改进,在更改代码之前,我可以成功加载小于150个用户的测试。

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

//code
}


System.Transaction.TransactionException:操作对事务状态无效。 --->System.TimeOutException:事务超时。底层提供者开放失败。


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

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
System.TimeOutException:事务超时。底层提供者开放失败。
看起来你的连接没有关闭。我的理论是你使用的是一个以上的连接。检查明确打开的连接并检查一旦事务执行,则连接也在关闭之后。

每个用户通常允许一个连接和内部连接,用户可以在给定范围内执行多个查询。如果打开多个连接,则第二个连接将阻止您的查询运行。您只能在该实例上运行事务打开第一个连接。如果您正在创建连接的新实例,则请不要。每次都使用相同的实例。除非您知道您的前一个被正确丢弃,否则永远不会创建一个以上的连接实例。

我希望你读这个问题和接受的答案 堆栈溢出。我不喜欢经常链接到该网站,因为当他们不经常正确时被推动为接受的答案。没有人,我确定它会在这种情况下帮助你。

如果您使用的是IIS Express,请右键单击托盘图标并停止您的网站。这将释放,或者应该释放您的项目可能会阻塞的连接。
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
我会尝试这个,希望它有效。

TransactionScope和多线程

更新: 审核文档后 这里,我看到数据库.BegIntransaction()是首选的EF呼叫。但是,这假设我的所有更改都会发生在同一上下文中,这不会发生。短暂创建虚拟上下文并传递交易,我不相信这解决了我的问题。

我无法理解他做了什么来解决他的问题。
"更新: 审核文档后 这里,我看到数据库.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:

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
这是一个可怕的想法。并将多线程带入其中要求不必要的并发症。

似乎你有一个无视建议的小丑。关于我上面发布的两个连接问题呢?你会再次遇到同样的问题。

EF是懒惰的人,不想用Linq / SQL弄脏和脏污。为什么不仅仅是学习灵招?

我看到database.begintransaction()是首选的EF呼叫。
它是什么,您的连接池是阻止的,因为连接的代码,而不是您的交易。我们再次进入圈子。您需要更改代码以适应使用所有查询的一个连接。

在您之前对您提出一些更改之前,我无法进一步帮助您,直到您不再忽略建议。

编辑:拼写错误
 
Last edited:

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
好的,当我运行操作方法时,我会检查db以查看是否有超过1个连接。如果有,我会尝试更改为代码。谢谢你。
 

sh

众所周知的成员
加入
2018年9月5日
消息
1,982
编程经验
10+
这是根据我的思想,进步和对此的有限体验的重要意见。你可能想先喝一杯茶!

在MySQL Server中,您可以检查信息_Schema以获取连接进程,但在SQL Server中,我认为您必须按命令行执行此操作。您应该检查代码,而不是您的数据库。我们从最后的错误中知道,您的连接现在未在某些时候结束。在第15章上,我强烈反对第一个链接的建议,因为我看不到它会如何完成任何事情。我有一个与EF一起合作的同事,而不是我,我从来没有个人的粉丝,我也不会认为自己是过度自信的EF用户,但我知道足以得到。大多数是在看他时,当他任务在我们公司中使用它时。

使用块使用块并封装连接并在其内执行命令。这就是我在想什么......我在认为你应该创建一个SQL管理类,它将为您处理所有连接并绕过EFS自动连接管理。这样,您可以明确打开和关闭连接,其中命令需要执行,您可以处理自己的连接,并管理其连接状态。除非您明确打开/关闭它们,否则您不能与EF一起这样做。 (至少不是我的知识。)我已经读过人们创造了我称之为SQL Management的工厂课程。当命令需要执行时,这将责备管理您的连接,然后将您的SQL工厂类负责处理,所以如果这是您可能考虑的话,请确保其何时达到PAR它符合可靠性和可重新可用性。

根据 布伦特ozar.,EF不会干扰用户明确打开的连接。虽然,我相信旧版本的EF也用于关闭它们。什么是屁股的痛苦,但这不再是EF6的问题,我不这么认为。虽然这是我第一次实际上有足够的时间来缩短你的第一篇文章,并且正确地确定所指出的内容。我建议开始。我不会重写任何东西,抛弃它。我一直在思考你的选择,而我知道挖掘EF可能是不利的。我认为它会以故障排除,性能,学习和写入更可靠的代码来缓解您的痛苦。我实际上发现了一些代码......好吧; ucky跟随。

我理解为什么你使用EF,如大多数开发者,它将是或者是为了缓解负担并加快开发。是的,你得到了迅速的发展,但你最终交易表演,主要是因为信息的方式,数据如何在EF中解释,并不是我将自上交易的东西。 (表现)。并且由于您的压力测试有过多的数字(默认值的三次),我将假设您希望应用程序成为忙碌的应用程序,如果是这种情况;你真的是最能实现EF吗?

详细说明我上面的最后一点。如果您希望数据库规模增大,或者如果您需要其他字段,列,表格等,则会发生什么,这将在以后对您感到严重的问题,(特别是如果您决定远离EF到更多手动集成),随着与LINQ的集成将获得非常复杂的,这将是我避免的东西。但是干草,如果您确定您的应用程序DB不需要更改,或者需要扩展线路,那么您没有什么可担心的。

我认为如果您实施了八个左右主题的许多建议,您将获得更多的反馈。当跳伞运动员已经在其他地方说话时,在担心性能之前,可以让您的申请执行缺陷。如果您的上述备注应考虑或执行我的建议,我也很好奇,如果一个人才能实现自己的SQL工厂类以管理连接,那么我的建议就会使用Unity / EF的目的我建议是因为我已经从遭受同样问题的许多用户阅读了报告。

让你思考的东西 @ raysefo..
 

Raysefo.

众所周知的成员
加入
2019年2月22日
消息
204
编程经验
10+
我对你们有个好消息。我用1000个用户进行了负载测试,10秒钟升温时间,没有错误 :) 我刚刚从代码中删除了事务范围。
 
最佳 底部