我正在开发一个使用大量自定义类的项目,每个自定义类都有效地表示来自数据库的一行数据。当有多个数据元素时,我一直在这样做:
public class Client
{
private int _clientID;
private double _annualRevenue;
public int ClientID
{
get { return _clientID; }
set { _clientID = value; }
}
public double AnnualRevenue
{
get { return _annualRevenue; }
set { _annualRevenue = value; }
}
}
然后,代码中的其他地方......
public class QueryClients
{
private List<Client> _clients;
public List<Client> FindClientByRevenue(double minimumRevenue)
{
List<Client> returnValue = (from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
return returnValue;
}
}
这很好用,但恕我直言,要在代码中的其他地方继续声明这个列表是很难看的。我将不得不在至少100个不同的地方使用它。我想通过使用有意义的名称创建一个自定义类来简单地表示List,来清理它。我的意思是像这样的东西:
public class Clients : List<Client> { }
现在这个工作,但LINQ查询的结果不会强制转换为IMPLICITLY。所以忍受我。如果新代码看起来像这样......
public class QueryClients
{
private Clients _clients;
public QueryClients(Clients clients)
{
_clients = clients;
}
public Clients FindClientByRevenue(double minimumRevenue)
{
Clients returnValue = (from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
return returnValue;
}
}
...我收到编译错误:
CS0266
Cannot implicitly convert type 'System.Collections.Generic.List<Client>' to 'Clients'. An explicit conversion exists (are you missing a cast?)
好的,好的,所以我可以通过EXPLICITLY转换LINQ查询的结果来消除IDE中的编译器错误:
public class QueryClients
{
private Clients _clients;
public QueryClients(Clients clients)
{
_clients = clients;
}
public Clients FindClientByRevenue(double minimumRevenue)
{
Clients returnValue = (Clients)(from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
return returnValue;
}
}
代码甚至编译得很好。但是一旦我点击那个查询,它就会爆炸。
Clients clients = new Clients();
Client client;
client = new Client();
client.ClientID = 1;
client.AnnualRevenue = 100;
clients.Add(client);
client = new Client();
client.ClientID = 2;
client.AnnualRevenue = 200;
clients.Add(client);
client = new Client();
client.ClientID = 3;
client.AnnualRevenue = 300;
clients.Add(client);
QueryClients q = new QueryClients(clients);
Clients clients2 = q.FindClientByRevenue(200);
当然,这是一个投射错误。
An unhandled exception of type 'System.InvalidCastException' occurred.
Additional information: Unable to cast object of type 'System.Collections.Generic.List`1[Client]' to type 'Clients'.
所以即使它编译,它也不会运行,即使这种方法DID工作,它也没有真正解决我的问题,因为那时我必须显式地转换每个LINQ查询的结果,如果我有要做到这一点,我不妨在任何地方宣布列表。叹息。
所以无论如何,我做错了什么,我只是看不出怎么做才能解决它。我确信,至少我需要在我的Clients类中添加某种转换/转换运算符,以允许隐式转换(或其他)。我根据众多不同的Google搜索尝试了很多不同的东西,它要么无法编译,要么无法运行。我只是想不出来。
有两个目标:
1。)在我的代码中使用Clients对象,而不是一遍又一遍地声明一个列表变量。
2.。)能够运行LINQ查询,从一个Clients对象中选择一些Client对象到另一个(新的)Clients对象。
这可能吗?你真的可以告诉我如何修改Clients类以便它可以工作(隐式地转换)吗?如果可以做到,我确信这很简单,我会在发布之前自己没有看过它。
提前感谢您的见解。
答案 0 :(得分:1)
我道歉但改变了这一点:
public class QueryClients
{
private List<Client> _clients;
public List<Client> FindClientByRevenue(double minimumRevenue)
{
List<Client> returnValue = (from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
return returnValue;
}
}
到此:
public class QueryClients
{
private Clients _clients;
public List<Client> FindClientByRevenue(double minimumRevenue)
{
Clients returnValue = (from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
return returnValue;
}
}
没有意义。
您希望使用Clients
类型与List<Client>
完全相同
因此,如果您继续使用List<Client>
通用List
可以拥有的所有权益,那么似乎会更好。
答案 1 :(得分:1)
警告:不要这样做,坚持List<Client>
,但出于教育原因,下面是答案
你有很多选择,首先是让你的类作为构造函数参数IEnumerable<Client>
public class Clients : List<Client>
{
public Clients(IEnumerable<Client> clients)
: base(clients){}
}
然后作为您的查询
Clients returnValue = new Clients(from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c);
另一种方法是提供一个明确的强制转换,以便在IList<Client>
中执行相同操作,但您必须将Clients
类更改为不继承List<Client>
。
public class Clients
{
private List<Client> list;
public Clients(IEnumerable<Client> clients)
{ this.list = clients.ToList(); }
public static explicit operator Clients(List<Client> list)
{
return new Clients(list);
}
}
这会允许类似原始代码的内容
Clients returnValue = (Clients)(from c in _clients
where c.AnnualRevenue >= minimumRevenue
select c).ToList();
答案 2 :(得分:0)
您应该创建一个链接到数据库的.dbml文件,您可以在该数据库中添加您希望模型类查询数据库的所有SQL表。这也将自动生成类,而无需编写任何代码。之后,您可以修改从数据库查询的此模型的实例并提交更改。没有一个SQL查询要写入更新或删除。一切都由LINQ处理。
这是一个很好的演练: https://msdn.microsoft.com/en-us/library/bb384428.aspx
一旦设置完毕,您所要做的就是: //创建DataContext
MyDataContext context = new MyDataContext(myConnectionString)
//查询一些客户端 - 客户端类将由LINQ
自动生成列表&lt;客户&gt; clients =(来自客户端的context.Clients,其中CONDITON选择客户端).ToList()
//根据需要修改这些客户端 //提交对数据上下文的更改(将自动从此数据上下文更新已修改的类)
context.SubmitChanges()
答案 3 :(得分:-1)
你得到一个强制转换异常,因为列表查询结果的动态类型是List<Client>
而不是从它继承的客户端(你不能从'动物'转换为'狗'对象实际上并不是“狗”。
由于您不能从基类进行任何用户定义的转换,我建议删除继承并添加隐式(或显式转换):
public class Clients {
private List<Client> d;
public Clients(List<Client> d)
{
this.d = d.ToList();
}
public static implicit operator Clients(List<Client> d)
{
return new Clients(d);
}
}
然而,这不允许您将客户端视为可枚举。或者,您可以使用以下签名为IEnumerable<Client>
编写扩展方法:
public static Clients ToClientList(this IEnumerable<Client> input){
return new Clients(input);
}
作为旁注,我认为使用List<Client>
比定义自己的类更优雅和清晰..