我试图通过一部分数据检索来熟悉自己的教育目的。我有几个不同的数据模型,我想填充。我没有使用对象关系映射器或为每种形式的检索重建奇异方法,而是考虑了所述方法:
public List<T> BuildModel<T>(string query) where T : new()
{
var container = new List<T>();
using(var connection = new SqlConnection(dbConnection))
using(var command = new SqlCommand(query, connection))
{
connection.Open();
using(var reader = command.ExecuteReader())
while(reader.Read())
{
T model = new T();
// How can I associate said data column, to the property in model?
container.Add(model);
}
}
return container;
}
我的方法是否可行,还是我离得很远?我觉得我应该能够访问所说的Anonymous Types
来构建模型。我不确定这是可能的,但我觉得应该是这样。如上所述,这是出于教育目的。
答案 0 :(得分:2)
你最终使用是一个ORM(尽管不是一个非常完整的功能),但这是一个非常基本的例子:
public List<T> BuildModel<T>(string query) where T : new()
{
var container = new List<T>();
var properties = typeof(T).GetProperties();
using (var connection = new SqlConnection(dbConnection))
using (var adapter = new SqlDataAdapter(query, connection))
{
connection.Open();
var table = new DataTable();
adapter.Fill(table);
foreach (DataRow row in table.Rows)
{
T item = new T();
foreach (PropertyInfo property in properties)
{
if (table.Columns.Contains(property.Name))
{
property.GetSetMethod().Invoke(item, new[] { row[property.Name] });
}
}
container.Add(item);
}
}
return container;
}
这使用反射来尝试查看每个(公共)属性是否作为结果集中的列存在。属性名称必须与列名完全匹配。
假设你有一张桌子Person
:
create table [Person]
(
[Id] int not null,
[FirstName] nvarchar(100) not null,
[LastName] nvarchar(100) not null
);
以及相应的班级Person
:
public class Person
{
public int Id { get; set; }
public string FirstName { get; set;}
public string LastName { get; set; }
}
用法是:
var people = BuildModel<Person>("select * from Person");
另外,关于匿名类型 - 我不确定它们是否真的适用于此(你的意思是dynamic
?)。如果要返回匿名类型列表,则需要在BuildModel
上抛弃类型参数并返回List<object>
。
答案 1 :(得分:0)
我建立的方法:
private List<T> Build<T>(string query) where T : new()
{
var container = new List<T>();
using(var connection = new SqlConnection(dbConnection))
using(var command = new SqlCommand(query, connection))
{
connection.Open();
using(var reader = command.ExecuteReader())
while(reader.Read())
{
T model = new T();
var columns = Enumerable.Range(0, reader.FieldCount).Select(reader.GetName).ToList();
var type = model.GetType();
foreach(var property in type.GetProperties())
foreach(var column in columns)
if (String.Compare(property.Name, column, true) == 0)
if(!reader.IsDBNull(reader.GetOrdinal(property.Name)))
property.SetValue(model, reader.GetValue(reader.GetOrdinal(property.Name)), null);
container.Add(model);
}
}
return container;
}