C#如何根据标志

时间:2018-06-05 10:38:25

标签: c# database entity-framework asp.net-web-api2

我正在尝试在C#Webapi项目中创建一个公共函数,以根据输入标志的值连接到两个数据库之一。每个数据库都具有相同的结构,但不同的数据和每次调用将始终使用相同的数据库。

我的其余代码与数据库无关,因此它需要能够使用公共db对象,而不是每次调用数据库时都做出决定。

这是我认为可以解决问题的代码:

public static dynamic GetDb(string scope = "dev") {
    dynamic db;

    if (Globals.db == null) {
        switch (scope.ToLower()) {
        case "tns":
            db = new TnsDb();
            break;

        case "sng":
            db = new SngDb();
            break;

        default:
            db = new TnsDb();
            break;
        }

        Globals.db = db;
    } else {
        db = Globals.db;
    }

    return db;
}

我正在使用Entity Framework,它为我连接到项目的每个数据库创建了一个访问类,并为我需要访问的每个存储过程包含一个方法。我想做的是让这个常用方法返回一个代表相应数据库类的对象。

我遇到的问题是该方法没有返回可用对象。我已经尝试使用返回类型的动态(如上所述),普通对象和DbContext(实体框架db类的父类)以及其他一些绝望的事情,但每次调用语句都收到一个对象实体框架数据库类中没有任何方法。

任何有关如何动态选择和返回保留所有方法的适当对象的想法都会感激不尽,因为我至少可以节省一些头发。

2 个答案:

答案 0 :(得分:0)

您提到每个数据库具有相同的结构,但您的函数使用不同的数据库上下文。您无法使用动态对象在此上下文中使用动态对象。

由于您的db具有相同的结构,因此您可以在初始化DbContext时将连接字符串更改为db。如果你真的想使用单独的db上下文,那么你应该使用你的函数返回的interfact

collection-A

并且你们两个上下文都需要实现这个,那么你的功能就像这样

collection-B

但是你不应该使用两个单独的数据库上下文,只要在你的情况下使用不同的连接字符串就足够了

虽然为此目的使用静态函数并不是很好,但您可以使用依赖注入

来创建一些存储库模式

答案 1 :(得分:0)

成功!我最终创建了一个与db类具有相同方法的接口,并从常用方法返回该接口。

以下是该界面的摘录:

public interface IDatabase {
    ObjectResult<Method_1_Result> Method_1(Nullable<int> id, string username);
    ObjectResult<Method_2_Result> Method_2(string username, string password);
}

以下是db类的等效方法:

public partial class TnsDb : DbContext, IDatabase {
    public TnsDbDev()
        : base("name=TnsDb")
    {
    }

    public virtual ObjectResult<Method_1_Result> Method_1(Nullable<int> id, string username)
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Method_1_Result>("Method_1", idParameter, usernameParameter);
    }

    public virtual ObjectResult<Method_2_Result> Method_2(string username, string password)
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Method_2_Result>("Method_2", usernameParameter, passwordParameter);

    }
}

public partial class SngDb : DbContext, IDatabase {
    public SngDbDev()
        : base("name=SngDb")
    {
    }

    public virtual ObjectResult<Method_1_Result> Method_1(Nullable<int> id, string username)
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Method_1_Result>("Method_1", idParameter, usernameParameter);
    }

    public virtual ObjectResult<Method_2_Result> Method_2(string username, string password)
    {
        return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Method_2_Result>("Method_2", usernameParameter, passwordParameter);

    }
}

请注意,我必须从界面方法中删除get和set实体,因为它们不是必需的并且一直会产生错误。

我还怀疑这个解决方案特定于我需要连接到具有完全相同模式的两个数据库的情况,并且如果模式稍有不同将无法工作,因为他们无法共享相同的模式接口

该技术还要求您记住每次重新生成db类(在本例中为TnsDb类)时重新添加对接口的引用,并在每次更改任何方法时保持最新。 db class。

无论如何,我希望能帮助任何有同样问题的人。感谢所有帮助我解决这个问题。