因此,我正在为我的一个模型开发一个基本的 MySql 数据解析器,我只是想为此生成一个通用的 Get 方法,而不必将每个数据库表映射到模型。
我想以这种方式实现这一点,但我不知道如何实现。我将向您展示一些代码。
public class DatabaseHandler
{
public DatabaseHandler()
{
}
public DataSet Get<T>(string field = "id", string oper = ">", string input = "0") where T : BaseDataModel
{
DataSet ds = null;
using (var conn = Connection())
{
string query = string.Format("SELECT * FROM {0} WHERE {1} {2} {3}", typeof(T).Name.ToLower(), field, oper, input);
using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn))
{
ds = new DataSet();
adapter.Fill(ds);
}
}
return ds;
}
private MySqlConnection Connection()
{
return new MySqlConnection("server=localhost;database=trainingsschema;uid=trainingsschema;pwd=password;");
}
}
然后我目前拥有的模型:
public class Onderdeel : BaseDataModel
{
public Onderdeel() : base() { }
public virtual string Naam { get; set; }
}
基础:
public class BaseDataModel
{
public BaseDataModel()
{
}
public virtual int Id { get; set; }
}
因此,如果我想将此数据集的结果解析为 List<Onderdeel>
我必须映射此 DatabaseHandler.Get<T>()
之外的每个表。方法。我会使用这段代码来做到这一点:
myDataSet.Tables[0].AsEnumerable()
.Select(i => new ClassName() {
i.MyProperty = dataRow.Field<String>("MyDatabaseFieldName")
}.ToList();
我想要归档的是一个简单的映射器,其中数据库字段名称位于属性的元数据中。
所以我的模型会变成这样:
[FieldName("identifier")]
public virtual int Id { get; set; }
[FieldName("naam")]
public virtual string Name { get; set; }
然后我想更换
i.MyProperty = dataRow.Field<String>("MyDatabaseFieldName")
使用一个循环遍历模型的所有属性并将它们映射到我附加到它的“FieldName”,DataType 也不会成为问题,因为它就在那里。最后是DatabaseHandler.Get<T>()
然后可以返回 List<T>
而不是DataSet
。
谁能帮助我?
最佳答案
几个小时后没有人回复,所以我不得不做一些调查。对于任何尝试这样做的人:
添加一个名为
FieldName
的新类[AttributeUsage(AttributeTargets.Property)] public class FieldName : Attribute { public FieldName(string text) { this.Text = text; } public string Text { get; set; } }
确保您有一个像我一样的基本模型,并用它扩展任何数据库模型,同时添加
FieldName
每个可映射属性的属性public class BaseDataModel { public BaseDataModel() { } [FieldName("id")] public int Id { get; set; } }
将此数据库助手添加到您的项目中(当然您也可以实现我的代码)
public class DatabaseHandler { public DatabaseHandler() { } public List<T> Get<T>(string field = "id", string oper = ">", string input = "0") where T : BaseDataModel { List<T> list = new List<T>(); DataSet ds = null; using (var conn = Connection()) { string query = string.Format("SELECT * FROM {0} WHERE {1} {2} {3}", typeof(T).Name.ToLower(), field, oper, input); using (MySqlDataAdapter adapter = new MySqlDataAdapter(query, conn)) { ds = new DataSet(); adapter.Fill(ds); } foreach (DataRow row in ds.Tables[0].Rows) { object obj = Activator.CreateInstance(typeof(T)); foreach (PropertyInfo propertyInfo in typeof(T).GetProperties()) { if (propertyInfo.CanWrite && propertyInfo.CanRead) { string fieldName = propertyInfo.CustomAttributes.ElementAt(0).ConstructorArguments[0].Value.ToString(); if (fieldName == null) continue; propertyInfo.SetValue(obj, row.Field<dynamic>(fieldName)); } } list.Add(obj as T); } } return list; } private MySqlConnection Connection() { return new MySqlConnection("server=localhost;database=trainingsschema;uid=trainingsschema;pwd=password;"); } }
这是即插即用的,您的属性只有 1 个属性,如果您有更多属性,您可能希望根据正确的自定义属性及其值进行过滤。
现在您可以调用任何
List<T>
从你的数据库中这样:List<Onderdeel> onderdelen = _db.Get<Onderdeel>();
关于来自 MySql 表解析器的 C# DataSet,属性中包含数据库字段名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58145845/