我有一个包含40个表的Sql DB,我构建了代表每个表的模型,我还使用Dapper作为我的ORM。。。
我正在DAL(数据访问层(中构建CRUD语句,该DAL将采用myModelObj
(通过HTTPPost传入(和modelName
(通过URL参数传入(
我还有一个方法(MyMapper
(,它将把我的myModelObj
映射到我的模型-但是我创建的方法是object
类型,它返回System.Object
类型-我希望发生的是该方法返回模型并在运行时动态转换调用方法的数据类型,以匹配返回的模型类型。。。
我的代码:
控制器
private readonly IDbOperation _dbo;
...
...
public DataController(IDbOperation dboperation)
{
_dbo = dboperation;
}
...
[HttpPost("create/{modelName}", Name = "Generic CRUD: Create Method")]
[Produces("application/json")]
public ActionResult Create([FromBody] JObject createObject, string modelName)
{
try
{
... ... ...
object response = _dbo.CreateRecord(createObject, modelName);
// HTTP Post Body example
{
"Fullname": "Juan Carlos",
"Firstname": "Juan",
"Lastname": "Carlos",
"Salutation": "Dr.",
"Age": 30,
"CreatedOn": "2019-11-07T12:25:10"
}
数据库操作
private readonly IDbConnector _dbConnector
...
public DbOperation(IDbConnector dbConnector)
{
_dbConnector = dbConnector;
}
public JsonResult CreateRecord(JObject model, string modelName)
{
... ... ...
var create = MyMapper(modelName, model); // <<<
... ...
try
{
using (var connection = _dbConnector.GetMsSqlConnection())
{
// https://dapper-tutorial.net/insert
var createdId = connection.Insert(create);
...
}
}
}
private object MyMapper(string modelName, JObject mod)
{
switch (modelName.ToLower())
{
case "transaction":
return JsonConvert.DeserializeObject<ModelRepoDTO.Transaction>(model.ToString());
case "items":
return JsonConvert.DeserializeObject<ModelRepoDTO.Items>(model.ToString());
case "users":
return JsonConvert.DeserializeObject<ModelRepoDTO.Users>(mod.ToString());
...
...
default:
_logger.Error("DataAccessLayer", "DbOperation", ">>> Mapping decision could not be made");
break;
}
}
DbConnector
public class DbConnector : IDbConnector
{
private readonly string _connectionstring;
public DbConnector(IConfiguration config)
{
_connectionstring = config.GetValue<string>("Connectionstring");
}
public SqlConnection GetMsSqlConnection()
{
SqlConnection conn = null;
try
{
conn = new SqlConnection(_connectionstring);
conn.Open();
if (conn.State != ConnectionState.Open)
{
// throw error
}
}
catch (Exception ex)
{
if (conn != null && conn.State == ConnectionState.Open)
{
conn.Close();
}
conn = null;
}
// return the connection
return conn;
}
}
(当前(从MyMapper("User", {<Object from HTTP Post>})
返回的数据类型是System.Object
,因为MyMapper
是object
类型
我想要的是动态更改数据类型以匹配模型。。。
MyMapper("User", {<Object from HTTP Post>})
=>数据类型=User
请记住,我可以对40个不同的表/模型进行CRUD操作,显然在运行时之前我不知道调用哪一个。。。
(完成示例(…我获取从MyMapper
返回的对象并将其传递给connection.insert(...);
(我修改了我的帖子以显示这一点-查看DbOperation(
有什么建议吗?想法?
如果我理解你的问题,你试图在不预先知道泛型类型参数的情况下调用第三方(Dapper(泛型方法,而泛型类型参数通常必须在编译时提供。
这可以通过反射来实现。在你的包装类(我相信你称之为"DbConnector"(中,添加一个名为"InsertDynamicObject"的新方法,并对其进行编码,使其使用反射来找到你想要调用的方法定义。然后可以调用MakeGenericMethod,传递泛型类型参数。例如:
namespace Dapper //This is a stub for the Dapper framework that you cannot change
{
class DbConnection
{
public void Insert<T>(T obj)
{
Console.WriteLine("Inserting an object with type {0}", typeof(T).FullName);
}
}
}
namespace MyProgram
{
class DbConnector //Here is your DbConnector class, which wraps Dapper
{
protected readonly Dapper.DbConnection _connection = new Dapper.DbConnection();
public void InsertDynamicObject(object obj)
{
typeof(Dapper.DbConnection)
.GetMethod("Insert")
.MakeGenericMethod(new [] { obj.GetType() })
.Invoke(_connection, new[] { obj });
}
}
public class Program
{
public static void Main()
{
object someObject = "Test"; //This is the object that you deserialized where you don't know the type at compile time.
var connector = new DbConnector();
connector.InsertDynamicObject(someObject);
}
}
}
输出:
Inserting an object with type System.String
以下是DotNetFiddle上一个工作示例的链接:链接