[英]C# - How to return a Generic List based on a passed parameter to the Method
[英]C# how to return 1 row from List<T> object passed as parameter
我需要从我的函数 Selectus 返回一行列表。
所以我传递给反映数据库表字段的函数 Selectus 对象,我需要返回与参数looking_for 匹配的一行:
public static List<T> Selectus<T>(string looking_for)
{
//all select data
var db = OrmLiteBaza().Open();//opening database
var select_all_list = db.Select<T>();//getting all data for <T> object works fine
db.Dispose();
//try to select one row - here I have trouble:
var prop = typeof(T).GetProperties();//properties of passed <T> object
var list_selected_record = from records in select_all_list where prop[1].Name == looking_for select records;//tryin to select one record from <T> object as in looking_for variable
return list_selected_record.ToList();//here one record should be returned
}
假设 T 参数不同,我不知道如何从列表中选择一行。 在 SelectusT> 方法中,我想将反映数据库表中字段的不同对象作为 T 传递,而不是为每个选择创建单独的方法。 例如调用 Selectus,其中传递的对象是 public class ProductCodes { public int ID { get; 放; } 公共字符串 SapIndex { 获取; 放; } 公共字符串 SapName { 获取; 放; } }。 然后我想为另一个表调用另一个Selectus<ProductTypes>
等等......所以我想编写通用/整体方法并将其普遍用于我的所有类型的对象,这反映了几个数据库表的字段。 SapIndex 属性始终位于所有对象的相同位置...
使用prop[1]
非常脆弱。 谁说你目前感兴趣的房产总是排在第二位? 如果有人明天添加另一个属性怎么办? 如果不是您使用的每个 T 在其属性列表中的第二位都具有相同的属性怎么办? 目前还不清楚你的实际目标是什么,以及你为什么要采取反思路线。
你最好在这里使用继承或接口实现。 我将在这个答案中使用一个界面,但任何一个都可以。
为了清楚起见,我们假设在所有可能的列表中都有一个Code
字段,这是您尝试匹配的属性。
public interface ICodeEntity
{
string Code { get; }
}
Selectus
方法的所有类。public class Person : ICodeEntity
{
public string Code { get; set; }
// And other properties
}
public class Document : ICodeEntity
{
public string Code { get; set; }
// And other properties
}
T
的使用限制为仅用于实现您的接口的类型。public static List<T> Selectus<T>(string code)
where T : ICodeEntity
Code
属性的相关类型的方式编写代码,并且编译器将帮助执行它。var db = OrmLiteBaza().Open();
var list = db.Select<T>().ToList();
db.Dispose();
return list.Where(item => item.Code == code).ToList();
List<Person> peopleWithCodeABC = Selectus<Person>("ABC");
List<Person> documentsWithCodeXYZ = Selectus<Document>("XYZ");
// This will fail if Animal does not implement ICodeEntity
var compilerError = Selectus<Animal>("ABC");
您可以更改代码以仅返回一个元素
public static T Selectus<T>(string looking_for)
{
//all select data
var db = OrmLiteBaza().Open();//opening database
var select_all_list = db.Select<T>();//getting all data for <T> object works fine
db.Dispose();
//try to select one row - here I have trouble:
var prop = typeof(T).GetProperties();//properties of passed <T> object
var list_selected_record = from records in select_all_list where prop[1].Name == looking_for select records;//tryin to select one record from <T> object as in looking_for variable
return list_selected_record.FirstOrDefault();//here one record should be returned
}
我可能不完全理解您想要的内容,但是您可以通过func Func<,>
代表的委托,而不是string looking_for
。
就像是:
public static List<TField> Selectus<T, TField>(Func<T, TField> selector)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
var list_selected_record = select_all_list.Select(selector); // 'using System.Linq;'
return list_selected_record.ToList();
}
然后我相信它可以这样称呼:
var list_one = Selectus((ProductCodes x) => x.SapIndex);
var list_two = Selectus((ProductTypes x) => x.SapIndex);
var list_three = Selectus((ProductCodes x) => x.SapName);
使用这种语法,我省略了该方法的<ProductCodes, string>
通用参数,因为它们可以被推断出来。
嗯,也许你想要它在相反的维度。 你可以这样做:
public static List<T> Selectus<T>(Func<T, bool> predicate)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
var list_selected_record = select_all_list.Where(predicate); // 'using System.Linq;'
return list_selected_record.ToList();
}
和:
var list_one = Selectus((ProductCodes x) => x.SapIndex == "ABC");
var list_two = Selectus((ProductTypes x) => x.SapIndex == "ABC");
var list_three = Selectus((ProductCodes x) => x.SapName == "DaName");
或者:
var list_one = Selectus<ProductCodes>(x => x.SapIndex == "ABC");
var list_two = Selectus<ProductTypes>(x => x.SapIndex == "ABC");
var list_three = Selectus<ProductCodes>(x => x.SapName == "DaName");
但是,如果它始终是“相同”的属性,就像x.SapIndex
一样(但对于不同类型的x
),那么 Flater 的答案看起来不错。
否则,如果你坚持,你的反思方法应该是可能的。 使用属性的名称,而不是它的索引! 让我试试:
public static List<T> Selectus<T>(string looking_for)
{
var db = OrmLiteBaza().Open();
var select_all_list = db.Select<T>();
db.Dispose();
const string prop_name = "SapIndex";
var prop = typeof(T).GetProperty(prop_name); // can blow up for bad T
var list_selected_record = select_all_list
.Where(x => (string)(prop.GetValue(x)) == looking_for); // 'using System.Linq;'
return list_selected_record.ToList();
}
和:
var list_one = Selectus<ProductCodes>("ABC");
var list_two = Selectus<ProductTypes>("ABC");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.