[英]C# how to return 1 row from List<T> object passed as parameter
I need to return one row of List from my function Selectus.我需要从我的函数 Selectus 返回一行列表。
So I pass to the function Selectus object that reflects database table fields and I need to return one row which match the parameter looking_for:所以我传递给反映数据库表字段的函数 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
}
I do not know how to select one row from the list assuming that T parameter is vary.假设 T 参数不同,我不知道如何从列表中选择一行。 In SelectusT> method I want to pass as T different objects which reflect fields in database table rather than creatinig separate methods for each select.
在 SelectusT> 方法中,我想将反映数据库表中字段的不同对象作为 T 传递,而不是为每个选择创建单独的方法。 eg call Selectus, where object passed is public class ProductCodes { public int ID { get;
例如调用 Selectus,其中传递的对象是 public class ProductCodes { public int ID { get; set;
放; } public string SapIndex { get;
} 公共字符串 SapIndex { 获取; set;
放; } public string SapName { get;
} 公共字符串 SapName { 获取; set;
放; } }.
} }。 Then I want to call another
Selectus<ProductTypes>
for another table etc... So I want to write generic/overall method and use it universally for all types of my objects which reflects the fields of few database tables.然后我想为另一个表调用另一个
Selectus<ProductTypes>
等等......所以我想编写通用/整体方法并将其普遍用于我的所有类型的对象,这反映了几个数据库表的字段。 The SapIndex property is always in the same place of all objects... SapIndex 属性始终位于所有对象的相同位置...
Using prop[1]
is incredibly fragile.使用
prop[1]
非常脆弱。 Who says that the property you're currently interested in is always going to be in second place?谁说你目前感兴趣的房产总是排在第二位? What if someone adds another property tomorrow?
如果有人明天添加另一个属性怎么办? What if not every T that you use have the same property in the second place on its list of properties?
如果不是您使用的每个 T 在其属性列表中的第二位都具有相同的属性怎么办? It is quite unclear what your actual goal is here and why you've taken the reflection route.
目前还不清楚你的实际目标是什么,以及你为什么要采取反思路线。
You would be better off using inheritance or interface implementation here.你最好在这里使用继承或接口实现。 I'm going to use an interface in this answer, but either would work.
我将在这个答案中使用一个界面,但任何一个都可以。
For the sake of clarity, let's assume there is a Code
field in all your possible lists, and this is the property you're trying to match with.为了清楚起见,我们假设在所有可能的列表中都有一个
Code
字段,这是您尝试匹配的属性。
public interface ICodeEntity
{
string Code { get; }
}
Selectus
method.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
only to types that implement your interface.T
的使用限制为仅用于实现您的接口的类型。public static List<T> Selectus<T>(string code)
where T : ICodeEntity
Code
property, and the compiler will help enforce it.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");
you can change code to return just one element您可以更改代码以仅返回一个元素
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
}
I might not understand fully what you want, but instead of string looking_for
you could pass in a Func<,>
delegate which acts as a selector.我可能不完全理解您想要的内容,但是您可以通过func
Func<,>
代表的委托,而不是string looking_for
。
Something like:就像是:
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();
}
Then I believe it could be called like this:然后我相信它可以这样称呼:
var list_one = Selectus((ProductCodes x) => x.SapIndex);
var list_two = Selectus((ProductTypes x) => x.SapIndex);
var list_three = Selectus((ProductCodes x) => x.SapName);
With this syntax I leave out the <ProductCodes, string>
generic arguments to the method since they can be inferred.使用这种语法,我省略了该方法的
<ProductCodes, string>
通用参数,因为它们可以被推断出来。
Hmm, maybe you want it in the opposite dimension.嗯,也许你想要它在相反的维度。 You could do:
你可以这样做:
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();
}
with:和:
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");
or:或者:
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");
But if it is going to always be the "same" property, like always x.SapIndex
(but for different types of x
), then Flater's answer looks good.但是,如果它始终是“相同”的属性,就像
x.SapIndex
一样(但对于不同类型的x
),那么 Flater 的答案看起来不错。
Otherwise, if you insist, your reflection approach should be possible.否则,如果你坚持,你的反思方法应该是可能的。 Use propety's name, not its index!
使用属性的名称,而不是它的索引! Let me try:
让我试试:
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();
}
with:和:
var list_one = Selectus<ProductCodes>("ABC");
var list_two = Selectus<ProductTypes>("ABC");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.