sapiens / SqlFu

Fast and versatile .net core data mapper/micro-orm
Other
229 stars 50 forks source link

Help migrating to v3 #97

Closed ahazelwood closed 7 years ago

ahazelwood commented 7 years ago

I've been using SqlFu v2 for quite a while, and it works great for our needs. However, I'm not sure how to map one of our current use cases over the the new v3.

We often have client data that drives which database connection string (some of which is dynamic in nature) to use. For example, we might have a Connection string that looks like: ..;Initial Catalog=Shard{0};... which we can currently replace the {0} with data from the client request, and use this to initialize our SqlFuConnection. I'm not sure how to map this dynamic connection string into the new SqlFuManager implementation along with DI that is at the heart of v3. Any pointers would be helpful, as I'd love to migrate to v3 as we move towards .net core.

Keep up the great work on SqlFu.

Thanks.

sapiens commented 7 years ago

That's an interesting use case. Try this

 //let's define 2  profiles one 'fixed' and one 'dynamic'
  SqlFuManager.Configure(c =>
            {
                c.AddProfile(new SqlServer2012Provider(SqlClientFactory.Instance.CreateConnection), "fixed conn string","default");
                c.AddProfile(new SqlServer2012Provider(SqlClientFactory.Instance.CreateConnection), "dynamic {0} conn string","dynamic");

            });

 public interface IFixedConnectionFactory : IDbFactory
    {

    }

    public class FixedConnectionFactory : DbFactory, IFixedConnectionFactory
    {

    }

    public interface IDynamicConnectionFactory : IDbFactory
    {

    }

Case 1

Now, I assume the connection string doesn't change very often (on request bases) so you can do this (not thread safe, but it can be made that way):

 //update the profile when you have the client data
 public static void UpdateConnection(string data)
        => SqlFuManager.Config.GetProfile("dynamic").ConnectionString = string.Format(DynamicFactory.ConnectionString, data);

 public class DynamicFactory : DbFactory ,IDynamicConnectionFactory
    {
        public const string ConnectionString = "bla {0}";

        public DynamicFactory():base(SqlFuManager.Config.GetProfile("dynamic"))
        {

        }
    }

Register into DI container , autofac example. Every dependency gets its own instance.

   builder.Register(c => new DynamicFactory()).As<IDynamicConnectionFactory>();

Case 2

Client data is specific for each request

 public class DynamicFactory : DbFactory ,IDynamicConnectionFactory
    {
        public const string ConnectionString = "bla {0}";

        public static IDynamicConnectionFactory GetInstance(string data)
        {
            var profile = new DbAccessProfile();
            profile.Provider = SqlFuManager.Config.GetProfile("dynamic").Provider;
            profile.ConnectionString= string.Format(DynamicFactory.ConnectionString, data);
            return new DynamicFactory(profile);
        }

        private DynamicFactory(DbAccessProfile profile):base(profile)
        {

        }   
    }

About DI container integration, basically you need to setup DynamicFactory.GetInstance(data) as a factory or to invoke it directly. This is specific to your app and style.

sapiens commented 7 years ago

Starting with ver 3.4.0 (released) you can override the connection string everytime you create a connection. This should make things easier for you.