none
Abstract Linq method RRS feed

  • Question

  • I have two different databases which were abstracted in Linqs through Linq4Templates: LINQA (LINQA.cs) and LINQB(LINQB.cs).They both have the same tables.

    Whenever I want to use them, I need to do:


    using (var dbA = new LinqA())
    {      
       query = from a in dbA.Table1 
    }
    using (var dbB = new LinqB())
    {      
       query = from a in dbB.Table1
    }


    How could I abstract those classes in a way I call them as generic and inside they the class could know if I'm using A or B?

    for instance:

    using (var db = new LinqDB("dbB"))
    {     
    query = from a in db.Table1 
    }




    • Edited by FcabralJ Monday, January 13, 2020 9:52 PM
    Monday, January 13, 2020 9:48 PM

Answers

  • Hello,

    Perhaps a DbContext factory as described here which talks about ASP.NET but should work for code first in a non ASP.NET project..


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, January 13, 2020 11:43 PM
    Moderator
  • The only abstraction you can do is make a custom class,   a container class, that represents both tables if the tables in two databases are the same, like a DTO.

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    You can use a Linq projection and project into a custom type like a DTO.

    https://csharp-station.com/Tutorial/Linq/Lesson02

    Sure, you can make some custom class the has a means to accept a flag to indicate which database table to use, do the Linq projection into the DTO and return the DTO(s) in a collection Lst<DTO> out of the method.

    Tuesday, January 14, 2020 12:52 AM
  • Hi FcabralJ,

    Thank you for posting here.

    It seems that similar functionality can be achieved using reflection.

    These codes may give you some ideas.

        class Program
        {
            static void Main(string[] args)
            {
                Type type = typeof(ClassA);
                ConstructorInfo magicConstructor = type.GetConstructor(Type.EmptyTypes);
                object magicClassObject = magicConstructor.Invoke(new object[] { });
                MethodInfo magicMethod = type.GetMethod("GetTable");
                object magicValue = magicMethod.Invoke(magicClassObject,null);
    
            }
        }
    
        class ClassA
        {
            public DataTable GetTable() 
            {
                using (SqlConnection conn = new SqlConnection(@"ConnString1"))
                {
                    conn.Open();
                    using (SqlCommand command = new SqlCommand("select * from emp",conn))
                    {
                        SqlDataReader reader = command.ExecuteReader();
                        DataTable dataTable = new DataTable();
                        dataTable.Load(reader);
                        return dataTable;
                    }
                }
            }
        }
    
        class ClassB
        {
            public DataTable GetTable()
            {
                using (SqlConnection conn = new SqlConnection(@"ConnString2"))
                {
                    conn.Open();
                    using (SqlCommand command = new SqlCommand("select * from emp", conn))
                    {
                        SqlDataReader reader = command.ExecuteReader();
                        DataTable dataTable = new DataTable();
                        dataTable.Load(reader);
                        return dataTable;
                    }
                }
            }
        }

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, January 14, 2020 6:10 AM

All replies

  • Hello,

    Perhaps a DbContext factory as described here which talks about ASP.NET but should work for code first in a non ASP.NET project..


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    Monday, January 13, 2020 11:43 PM
    Moderator
  • The only abstraction you can do is make a custom class,   a container class, that represents both tables if the tables in two databases are the same, like a DTO.

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    You can use a Linq projection and project into a custom type like a DTO.

    https://csharp-station.com/Tutorial/Linq/Lesson02

    Sure, you can make some custom class the has a means to accept a flag to indicate which database table to use, do the Linq projection into the DTO and return the DTO(s) in a collection Lst<DTO> out of the method.

    Tuesday, January 14, 2020 12:52 AM
  • Hi FcabralJ,

    Thank you for posting here.

    It seems that similar functionality can be achieved using reflection.

    These codes may give you some ideas.

        class Program
        {
            static void Main(string[] args)
            {
                Type type = typeof(ClassA);
                ConstructorInfo magicConstructor = type.GetConstructor(Type.EmptyTypes);
                object magicClassObject = magicConstructor.Invoke(new object[] { });
                MethodInfo magicMethod = type.GetMethod("GetTable");
                object magicValue = magicMethod.Invoke(magicClassObject,null);
    
            }
        }
    
        class ClassA
        {
            public DataTable GetTable() 
            {
                using (SqlConnection conn = new SqlConnection(@"ConnString1"))
                {
                    conn.Open();
                    using (SqlCommand command = new SqlCommand("select * from emp",conn))
                    {
                        SqlDataReader reader = command.ExecuteReader();
                        DataTable dataTable = new DataTable();
                        dataTable.Load(reader);
                        return dataTable;
                    }
                }
            }
        }
    
        class ClassB
        {
            public DataTable GetTable()
            {
                using (SqlConnection conn = new SqlConnection(@"ConnString2"))
                {
                    conn.Open();
                    using (SqlCommand command = new SqlCommand("select * from emp", conn))
                    {
                        SqlDataReader reader = command.ExecuteReader();
                        DataTable dataTable = new DataTable();
                        dataTable.Load(reader);
                        return dataTable;
                    }
                }
            }
        }

    Hope this could be helpful.

    Best Regards,

    Timon


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, January 14, 2020 6:10 AM