locked
Repository Async Question? RRS feed

  • Question

  • User-1104215994 posted

    Hi,

    I have <g class="gr_ gr_40 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace" id="40" data-gr-id="40">a IRepository</g> as follows:

     public interface IPinRepository : IDisposable
        {
            
            Task Add(Initiate initiate);
            
        }

    Here is my <g class="gr_ gr_57 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="57" data-gr-id="57">Reposiroty</g>:

    public class PinRepository : IPinRepository, IDisposable
        {
            private EPINMiddleWareAPIContext context;
    
            public PinRepository(EPINMiddleWareAPIContext context)
            {
                this.context = context;
            }
    
            public async Task Add(Initiate initiate)
            {
                context.Initiates.Add(initiate);
                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);
            }
        }

    I am confused, Should it be as follows?

    await context.Initiates.Add(initiate);

    Best Regards.

    Tuesday, February 19, 2019 5:51 AM

Answers

  • User-1104215994 posted

    I used Ninject for DI.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, February 23, 2019 11:26 AM

All replies

  • User475983607 posted

    Should we assume you are seeing an error or having some kind of problem when using this construct?  Can you explain the problem you are trying to solve?

    await context.Initiates.Add(initiate);

    Use the AddAsync() extension.

    https://docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.dbcontext.addasync?view=efcore-2.1

    I strongly recommend that you learn the async/await pattern before moving forward.

    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/async/

    Other than that, your question is not very clear.

    Tuesday, February 19, 2019 12:49 PM
  • User-1104215994 posted

    Hello <g class="gr_ gr_5 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="5" data-gr-id="5">mgebhard</g>,

    I will check your sources. When I change to this;

    await context.Initiates.AddAsync(initiate);

    I am getting this error;

    DbSet<Initiate> does not have definition for AddAsync and no accessible extension method...

    Tuesday, February 19, 2019 1:01 PM
  • User475983607 posted

    Hello mgebhard,

    I will check your sources. When I change to this;

    await context.Initiates.AddAsync(initiate);

    I am getting this error;

    DbSet<Initiate> does not have definition for AddAsync and no accessible extension method...

    You misunderstand.  The AddAsync() method belongs to the DbContext as clearly explained in the linked document.

    Tuesday, February 19, 2019 2:27 PM
  • User-1104215994 posted

    Is this correct usage then? I am trying to insert request data into <g class="gr_ gr_76 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins doubleReplace replaceWithoutSep" id="76" data-gr-id="76">database</g>.

    public async Task AddAsync(Initiate initiate)
            {
                context.Initiates.Add(initiate);
                await context.SaveChangesAsync();
            }

    Tuesday, February 19, 2019 2:38 PM
  • User475983607 posted

    Is this correct usage then? I am trying to insert request data into database.

    public async Task AddAsync(Initiate initiate)
            {
                context.Initiates.Add(initiate);
                await context.SaveChangesAsync();
            }

    The code shown is adding an entity using the DbSet.  Can you explain the problem you are trying to solve?   

    Tuesday, February 19, 2019 2:52 PM
  • User-1104215994 posted

    I am trying to insert request values in my controller. I am using <g class="gr_ gr_67 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar only-ins doubleReplace replaceWithoutSep" id="67" data-gr-id="67">repository</g>.

    [RoutePrefix("api/v2/pin")]
        public class InitiatesController : ApiController
        {
            private IPinRepository pinRepository;
    
            public InitiatesController()
            {
                this.pinRepository = new PinRepository(new EPINMiddleWareAPIContext());
            }
    
            public InitiatesController(IPinRepository pinRepository)
            {
                this.pinRepository = pinRepository;
            }
    
                   
            // POST: api/Game
            [HttpPost, Route("initiation")]
            //[ResponseType(typeof(Initiate))]
            public async Task<IHttpActionResult> PostInitiate(Initiate initiate)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                await pinRepository.Add(initiate);
                
    
                HttpClient httpClient = new HttpClient();
    
               
                HttpContent content = new StringContent(
                    JsonConvert.SerializeObject(initiate),
                    Encoding.UTF8,
                    "application/json"
                );
    
                
                HttpResponseMessage response =
                    await httpClient.PostAsync("https://test.com/purchaseinitiation", content);
    
                string htmlResponse = await response.Content.ReadAsStringAsync();
    
                return Ok(htmlResponse);
    
            }
    
            protected override void Dispose(bool disposing)
            {
                pinRepository.Dispose();
                base.Dispose(disposing);
            }
        }

    Tuesday, February 19, 2019 5:20 PM
  • User475983607 posted

    I am trying to insert request values in my controller. I am using repository.

    My best guess is this line of code does not save the initiate object in the database.  Is this correct?  Are there any errors?  If so, what are the error(s).  Have you tried setting a breakpoint to debug your code?

    await pinRepository.Add(initiate);

    Is this an ASP.NET Core Application like your other threads?  If so, this construct is incorrect or at best a questionable design.

            public InitiatesController()
            {
                this.pinRepository = new PinRepository(new EPINMiddleWareAPIContext());
            }

    Is this an ASP.NET application?  Can you share the constructor source?

    Can you explain why you are using a repository pattern?  

    Tuesday, February 19, 2019 5:41 PM
  • User-1104215994 posted

    My best guess is this line of code does not save the <g class="gr_ gr_9 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace" id="9" data-gr-id="9">initiate</g> object in the database.  Is this correct?  Are there any errors?  If so, what are the error(s<g class="gr_ gr_10 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation multiReplace" id="10" data-gr-id="10">).</g>  Have you tried setting a breakpoint to debug your code?

    I am not getting any errors. <g class="gr_ gr_200 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" id="200" data-gr-id="200">Actually</g> it inserts request data into <g class="gr_ gr_244 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins doubleReplace replaceWithoutSep" id="244" data-gr-id="244">database</g>.

    Is this an ASP.NET Core Application like your other threads?  If so, this construct is incorrect or at best a questionable design.

    Yep, It is an empty template web API application.

    Is this an ASP.NET application?  Can you share the constructor source?

    What do you mean by constructor source? I posted the sources in my previous posts.

    Can you explain why you are using a repository pattern?

    I read about web API design and repository pattern is <g class="gr_ gr_1622 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="1622" data-gr-id="1622">adviced</g> to use for <g class="gr_ gr_1715 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar only-ins replaceWithoutSep" id="1715" data-gr-id="1715">generic</g> structure. I would be glad if you can guide me to a <g class="gr_ gr_2156 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling multiReplace" id="2156" data-gr-id="2156">better tested</g> approach. 

    Tuesday, February 19, 2019 6:23 PM
  • User475983607 posted

    cenk1536

    I am not getting any errors. Actually it inserts request data into database.

    As I understand the code functions as expected.  I guess you just wanted to show your code?

    cenk1536

    What do you mean by constructor source? I posted the sources in my previous posts.

    I was referring the constructor code that you did not post.  You should use constructor injection.

            public InitiatesController()
            {
                this.pinRepository = new PinRepository(new EPINMiddleWareAPIContext());
            }

    cenk1536

    I read about web API design and repository pattern is adviced to use for generic structure. I would be glad if you can guide me to a better tested approach. 

    The code is very simple.  I don't get why you would use a repository pattern for one type with one method.  I would just inject the context.

    Anyway, my opinion is irrelevant because the code works as expected and I'm puzzled why you are posting in the first place.

    Tuesday, February 19, 2019 6:42 PM
  • User-1104215994 posted

    You should use constructor injection

    Should I use The Web API Dependency <g class="gr_ gr_21 gr-alert gr_gramm gr_inline_cards gr_run_anim Style multiReplace" id="21" data-gr-id="21">Resolver</g><g class="gr_ gr_21 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Style multiReplace" id="21" data-gr-id="21"> ?</g>

    Tuesday, February 19, 2019 7:46 PM
  • User475983607 posted

    Why???

    I assume the is an ASP.NET Core project using EF Core.  Register the DbContext in the ConfigureServices() method as illustrated in the EF Core docs.

    https://docs.microsoft.com/en-us/ef/core/get-started/aspnetcore/new-db?tabs=visual-studio

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<CookiePolicyOptions>(options =>
        {
            // This lambda determines whether user consent for non-essential cookies is needed for a given request.
            options.CheckConsentNeeded = context => true;
            options.MinimumSameSitePolicy = SameSiteMode.None;
        });
    
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    
        var connection = @"Server=(localdb)\mssqllocaldb;Database=EFGetStarted.AspNetCore.NewDb;Trusted_Connection=True;ConnectRetryCount=0";
        services.AddDbContext<BloggingContext>
            (options => options.UseSqlServer(connection));
    
    }
    

    Once the DbContext is registered, simply inject the DbContext in any class constructor including the repository.  There is no good reason to use the dependency resolver.  Just  use the framework as intended.

    Frankly, you can remove the repository, inject the context into the controller constructor, and accomplish the same thing as you are now with two lines of code. 

    Tuesday, February 19, 2019 8:59 PM
  • User-1104215994 posted

    Thank you for your suggestions. Here <g class="gr_ gr_7 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace" id="7" data-gr-id="7">is</g> my DbContext and Controller. (I removed repository. ) I think it is OK now?

    public class EPINMiddleWareAPIContext : DbContext
        {
               
            public EPINMiddleWareAPIContext() : base("name=EPINMiddleWareAPIContext")
            {
            }
    
            public System.Data.Entity.DbSet<Initiate> Initiates { get; set; }
        }
    [RoutePrefix("api/v2/pin")]
        public class InitiatesController : ApiController
        {
           private EPINMiddleWareAPIContext context;
    
           public InitiatesController(EPINMiddleWareAPIContext context)
            {
                this.context = context;
            }
    
            
            // POST: api/Game
            [HttpPost, Route("initiation")]
           public async Task<IHttpActionResult> PostInitiate(Initiate initiate)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                context.Initiates.Add(initiate);
    await context.SaveChangesAsync();

    ...

    Wednesday, February 20, 2019 7:05 AM
  • User36583972 posted


    Hi cenk1536,

    hank you for your suggestions. Here is my DbContext and Controller. (I removed repository. ) I think it is OK now?

    You can make a test on your side.

    As you said your application is an empty template web API application(ASP.NET Core Application). I suggest you can go to the ASP.NET Core forum.

    Besides, when you start a new thread you can include all necessary code snippets for anyone else to be able to reproduce your issue from scratch along with a detailed description about the results including any exception messages.

    Thank you for your understanding.

    Best Regards,

    Yong Lu

    Thursday, February 21, 2019 7:04 AM
  • User-1104215994 posted

    I am getting this error; Type 'EPINMiddleWareAPI.Controllers.InitiatesController' does not have a default constructor. How can I fix this?

    [RoutePrefix("api/v2/pin")]
        public class InitiatesController : ApiController
        {
            private EPINMiddleWareAPIContext context;
    
            
            public InitiatesController(EPINMiddleWareAPIContext context)
            {
                this.context = context;
            }
    
    
            // POST: api/Game
            [HttpPost, Route("initiation")]
            public async Task<IHttpActionResult> PostInitiate(InitiateRequest initiate)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                context.InitiatesRequests.Add(initiate);
                await context.SaveChangesAsync();
    
                HttpClient httpClient = new HttpClient();
    
    
                HttpContent content = new StringContent(
                    JsonConvert.SerializeObject(initiate),
                    Encoding.UTF8,
                    "application/json"
                );
    
    
                HttpResponseMessage response =
                    await httpClient.PostAsync("https://teststore.gamesultan.com/purchaseinitiation", content);
    
                string htmlResponse = await response.Content.ReadAsStringAsync();
    
                return Ok(htmlResponse);
            }
    
            protected override void Dispose(bool disposing)
            {
                context.Dispose();
                base.Dispose(disposing);
            }
        }

    In previous posts, it is said that this constructor is incorrect. How should I write then?

    public InitiatesController()
            {
                this.pinRepository = new PinRepository(new EPINMiddleWareAPIContext());
            }

    Thursday, February 21, 2019 7:57 PM
  • User475983607 posted

    I am getting this error; Type 'EPINMiddleWareAPI.Controllers.InitiatesController' does not have a default constructor. How can I fix this?

    [RoutePrefix("api/v2/pin")]
        public class InitiatesController : ApiController
        {
            private EPINMiddleWareAPIContext context;
    
            
            public InitiatesController(EPINMiddleWareAPIContext context)
            {
                this.context = context;
            }
    
    
            // POST: api/Game
            [HttpPost, Route("initiation")]
            public async Task<IHttpActionResult> PostInitiate(InitiateRequest initiate)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                context.InitiatesRequests.Add(initiate);
                await context.SaveChangesAsync();
    
                HttpClient httpClient = new HttpClient();
    
    
                HttpContent content = new StringContent(
                    JsonConvert.SerializeObject(initiate),
                    Encoding.UTF8,
                    "application/json"
                );
    
    
                HttpResponseMessage response =
                    await httpClient.PostAsync("https://teststore.gamesultan.com/purchaseinitiation", content);
    
                string htmlResponse = await response.Content.ReadAsStringAsync();
    
                return Ok(htmlResponse);
            }
    
            protected override void Dispose(bool disposing)
            {
                context.Dispose();
                base.Dispose(disposing);
            }
        }

    In previous posts, it is said that this constructor is incorrect. How should I write then?

    public InitiatesController()
            {
                this.pinRepository = new PinRepository(new EPINMiddleWareAPIContext());
            }

    I suspect you did not register the EPINMiddleWareAPIContext in ConfigureServers() as illustrated in the example and reference documentation above.   

    Thursday, February 21, 2019 8:17 PM
  • User-1104215994 posted

    there is a misunderstanding I guess, I am using asp.net Web API 2.0

    I walked through this tutorial.

    https://docs.microsoft.com/tr-tr/aspnet/web-api/overview/data/using-web-api-with-entity-framework/

    Friday, February 22, 2019 6:50 AM
  • User475983607 posted

    there is a misunderstanding I guess, I am using asp.net Web API 2.0

    I walked through this tutorial.

    https://docs.microsoft.com/tr-tr/aspnet/web-api/overview/data/using-web-api-with-entity-framework/

    All your other posts are ASP.NET Core.  So you switched to ASP.NET Web API?  Secondly it seems you posted a question while the code is working as expected.

    Can you explain the problem you are trying to solve?

    Friday, February 22, 2019 11:16 AM
  • User-1104215994 posted

    My all posts are ASP.NET web API <g class="gr_ gr_43 gr-alert gr_gramm gr_inline_cards gr_run_anim Punctuation only-ins replaceWithoutSep" id="43" data-gr-id="43">not</g> Core. This is <g class="gr_ gr_60 gr-alert gr_gramm gr_inline_cards gr_run_anim Grammar multiReplace" id="60" data-gr-id="60">the misunderstanding</g>. I am getting I am getting Type 'EPINMiddleWareAPI.Controllers.InitiatesController' does not have a default constructor.

    public class EPINMiddleWareAPIContext : DbContext
        {
            
            public EPINMiddleWareAPIContext() : base("name=EPINMiddleWareAPIContext")
            {
            }
        
            public DbSet<InitiateRequest> InitiatesRequests { get; set; }
            public DbSet<InitiateResponse> InitiateResponses { get; set; }
        }
    
    
    [RoutePrefix("api/v2/pin")]
        public class InitiatesController : ApiController
        {
            private EPINMiddleWareAPIContext context;
    
            public InitiatesController(EPINMiddleWareAPIContext context)
            {
                this.context = context;
            }
    
    
            // POST: api/Game
            [HttpPost, Route("initiation")]
            public async Task<IHttpActionResult> PostInitiate(InitiateRequest initiate)
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }
    
                context.InitiatesRequests.Add(initiate);
                await context.SaveChangesAsync();
    
                HttpClient httpClient = new HttpClient();
    
    
                HttpContent content = new StringContent(
                    JsonConvert.SerializeObject(initiate),
                    Encoding.UTF8,
                    "application/json"
                );
    
    
                HttpResponseMessage response =
                    await httpClient.PostAsync("https://test.com/purchaseinitiation", content);
    
                string htmlResponse = await response.Content.ReadAsStringAsync();
    
                return Ok(htmlResponse);
            }
    
            protected override void Dispose(bool disposing)
            {
                context.Dispose();
                base.Dispose(disposing);
            }
        }
    
    

    Friday, February 22, 2019 12:57 PM
  • User475983607 posted

    My all posts are ASP.NET web API not Core. This is the misunderstanding. I am getting I am getting Type 'EPINMiddleWareAPI.Controllers.InitiatesController' does not have a default constructor.

    Go back to your original working code.

    Friday, February 22, 2019 1:50 PM
  • User-1104215994 posted

    thank you

    Friday, February 22, 2019 2:04 PM
  • User-1104215994 posted

    I used Ninject for DI.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Saturday, February 23, 2019 11:26 AM