Base solution for your next web application
Open Closed

AspNetZero with multiple databases #2317


User avatar
0
vnetonline created

Dear Support

I have a requirement to read/write data to another database, however i don't want to run migration on that database ... is that possible.

I have seen a sample project which shows you how to talk to multiple databases however migrations are enabled on both databases.

Thanks in advance for your help


9 Answer(s)
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You can set database initializer to null, in this way migrations will not be applied.

    Database.SetInitializer(new NullDatabaseInitializer<YourDbContext>());
    
  • User Avatar
    0
    vnetonline created

    Thanks for your reply.I have managed to setup all the plumbing.

    The table in the DB I want to read/write from doesn't have a primary key named Id it has a primary key named Pre_ID and it uses a GUID without the dashes for its Key, I am also can to use the AsyncCrudAppService so that we can expose CRUD via WepAPI.

    Can you please let me know how I can achieve this??

    Thanks and Kind Regards Vineet Belani

  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    You can see this issue for using Pre_ID instead of Id field. <a class="postlink" href="https://github.com/aspnetboilerplate/aspnetboilerplate/issues/586">https://github.com/aspnetboilerplate/as ... issues/586</a>

    But I don't know how to convert GUID without the dashes to a regular guid.

  • User Avatar
    0
    vnetonline created

    Dear Support

    I am still have issues comminicating with a DB on another server here is what I have done

    Created a ErpDbContext as follows and defied "Erp" connection string in web.config

    public class ErpDbContext : AbpDbContext
        {
            /* Define an IDbSet for each entity of the application */
    
            //VB - 2017-01-11 - Erp tables
            public virtual IDbSet<Person> Persons { get; set; }
    
    
            /* Setting "Default" to base class helps us when working migration commands on Package Manager Console.
             * But it may cause problems when working Migrate.exe of EF. ABP works either way.         * 
             */
            public ErpDbContext()
                : base("Erp")
            {
                
            }
    
    
        }
    

    Created a Person Entity in Core project

    [Table("Person")]
        public class Person : IEntity<string>
        {
    
            [Key]
            public virtual string Pre_ID { get; set; }
    
            public virtual string FirstName { get; set; }
    
            public virtual string LastName { get; set; }
    
            public virtual string Salutation { get; set; }
    
            [NotMapped]
            public string Id
            {
                get
                {
                    return Pre_ID;
                }
    
                set
                {
                    Pre_ID = value;
                }
            }
    
            public bool IsTransient()
            {
                return false;
            }
        }
    

    Created a PersonDto in Application project

    [AutoMap(typeof(Person))]
        public class PersonDto : IEntityDto<string>
        {
    
            public virtual string Pre_ID { get; set; }
    
            public string FirstName { get; set; }
    
            public string LastName { get; set; }
    
            public string Salutation { get; set; }
    
            public string Id
            {
                get
                {
                    return Pre_ID;
                }
    
                set
                {
                    Pre_ID = value;
                }
            }
        }
    

    Created IPersonAppService as follows

    public interface IPersonAppService : IAsyncCrudAppService<PersonDto, string, GetAllPersonsInput, CreatePersonInput, UpdatePersonInput>
        {
    
            Task<ListResultDto<PersonDto>> GetAllPersons();
    
        }
    

    Created PersonAppService as follows

    public class PersonAppService : AsyncCrudAppService<Person, PersonDto, string, GetAllPersonsInput, CreatePersonInput, UpdatePersonInput>,
            IPersonAppService
        {
    
            public PersonAppService(IRepository<Person, string> personRepository)
                :base(personRepository)
            {
    
            }
    
            public async Task<ListResultDto<PersonDto>> GetAllPersons()
            {
                var personList = await Repository.GetAllListAsync();
    
                return new ListResultDto<PersonDto>(personList.MapTo<List<PersonDto>>());
            }
    
    
        }
    

    When I go to Swagger UI I can see the CRUD

    app/person Show/Hide List Operations Expand Operations
    POST /api/services/app/person/GetAllPersons
    POST /api/services/app/person/Get
    POST /api/services/app/person/GetAll
    POST /api/services/app/person/Create
    POST /api/services/app/person/Update
    POST /api/services/app/person/Delete
    

    When I try to execute GetAll call I am getting the following error

    {
      "result": null,
      "targetUrl": null,
      "success": false,
      "error": {
        "code": 0,
        "message": "An internal error occurred during your request!",
        "details": null,
        "validationErrors": null
      },
      "unAuthorizedRequest": false,
      "__abp": true
    }
    

    Thanks in advance for your help

  • User Avatar
    0
    vnetonline created

    I have resolved this by looking in the logs file located in App_Data\Logs directory, It turns out i was spelling the Pre_ID wrong where it should be Per_ID.

    So Get and GetAll AsyncCrudAppService methods now are working.

    My next problem is to do with Create and Update, the existing DB has the Per_ID column set to required and needs to be populated with a unique identifier made out of a GUID with out dashes.

    Is there a way i can generate this in my CreatePersonInput. here is what i am trying but i get a Sustem.Overflow error.

    [AutoMapTo(typeof(Person))]
        public class CreatePersonInput : IEntityDto<string>
        {
    
            //public string Id { get; set; }
    
            public string FirstName { get; set; }
    
            public string LastName { get; set; }
    
            public string Salutation { get; set; }
    
            public string Id
            {
                get
                {
                    return Id;
                }
    
                set
                {
                    if (value == "" )
                    {
                        Id = Guid.NewGuid().ToString("N").ToUpper();
                    }
                }
            }
        }
    
  • User Avatar
    0
    ismcagdas created
    Support Team

    Hi,

    It is better to set Id property in your entities constructor. Can you try that ?

  • User Avatar
    0
    vnetonline created

    When I try that the Id is written as an empty string, can you please give me sample code how you would do it ??

  • User Avatar
    0
    ismcagdas created
    Support Team

    Can you share your latest code for Person entity ? We can go over that.

  • User Avatar
    0
    vnetonline created

    Here is my latest code for person entity in the core project

    [Table("Person")]
        public class Person : Entity<string>
        {
    
            //[Key]
            //public virtual string Pre_ID { get; set; }
    
            [Column("Per_ID")]
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public override string Id { get; set; } 
    
            public virtual string FirstName { get; set; }
    
            public virtual string LastName { get; set; }
    
            public virtual string Salutation { get; set; }
    
            //[NotMapped]
            //public string Id
            //{
            //    get
            //    {
            //        return Pre_ID;
            //    }
    
            //    set
            //    {
            //        Pre_ID = value;
            //    }
            //}
    
            public override bool IsTransient()
            {
                return false;
            }
        }