我的GUI正在调用一个执行某些linq工作的服务项目,并将数据返回到我的GUI。但是,我正在与方法的返回类型作斗争。经过一番阅读后,我将此作为我的方法:
public static IEnumerable GetDetailedAccounts()
{
IEnumerable accounts =(from a in Db.accounts
join i in Db.financial_institution on
a.financial_institution.financial_institution_id
equals i.financial_institution_id
join acct in Db.z_account_type on a.z_account_type.account_type_id
equals acct.account_type_id
orderby i.name
select new
{
account_id = a.account_id,
name = i.name,
description = acct.description
});
return accounts;
}
然而,我的来电者正在争吵。我认为我搞砸了返回类型,或者没有很好地处理来电,但它并没有像我希望的那样工作。
这就是我尝试从GUI调用该方法的方法。
IEnumerable accounts = Data.AccountService.GetDetailedAccounts();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("Accounts:");
Console.ForegroundColor = ConsoleColor.White;
foreach (var acc in accounts)
{
Console.WriteLine(string.Format("{0:00} {1}", acc.account_id, acc.name + " " + acc.description));
}
int accountid = WaitForKey();
然而,我的foreach和acc - 不起作用。 acc不知道我在方法中设置的名称,描述和ID。我至少接近正确吗?
答案 0 :(得分:4)
@BrokenGlass是正确的,问题的根源是您使用的是匿名类型。这导致您使用IEnumerable的非泛型版本,该版本不知道对象的类型。
不是使用dynamic
(这需要.NET 4.0,这可能会或可能不是您的问题),我建议您创建一个实际的Account
类。
这样您就可以返回IEnumerable<Account>
而非IEnumerable
。然后,您将能够使用这些属性,因为它知道它是一个帐户。
创建帐户类后,您的方法将变为:
public static IEnumerable<Account> GetDetailedAccounts()
{
IEnumerable<Account> accounts = (from a in Db.accounts
join i in Db.financial_institution on a.financial_institution.financial_institution_id
equals i.financial_institution_id
join acct in Db.z_account_type on a.z_account_type.account_type_id equals
acct.account_type_id
orderby i.name
select new Account {account_id = a.account_id, name = i.name, description = acct.description});
return accounts;
}
然后调用代码可以保持不变。
我想我应该指出var
不会像你想象的那样发挥作用。变量的类型仍然是编译时确定的,这意味着(大多数情况下)它只是一个快捷方式。您的示例与使用object
而不是var
的情况相同,因为IEnumerable
只能包含object
。
如果您在.NET中工作,我建议遵循.NET命名约定,AccountId
而不是account_id
,但这不会影响它是否有效。
答案 1 :(得分:1)
问题是您使用的是该方法的用户无法回送的匿名类型。一个简单的出路(除了反射或创建一个类)将使用dynamic,因为你知道你想要访问的属性是:
示例:(我非常承认)
public static IEnumerable GetAccounts()
{
return Enumerable.Range(0, 10)
.Select(x => new { Id = x, Name = "herbert" });
}
//...
foreach (dynamic account in GetAccounts())
{
Console.WriteLine(string.Format("Id: {0}, Name: {1}",
account.Id,
account.Name));
}
返回您的代码,这意味着只需更改调用代码:
foreach (dynamic acc in accounts)
{
Console.WriteLine(string.Format("{0:00} {1}", acc.account_id, acc.name + " " + acc.description));
}
答案 2 :(得分:0)
Davy8是正确的,并且创建自定义BusinessObject(AccountDetail)对于长期外部库生命周期来说是更好的解决方案(如果您在逻辑/代码中使用此AccountDetail),因为您可以根据需要自定义它 具有转移类(AccountDetail)可以轻松地让您在设计时绑定到某个UI并使项目的概念更加清晰,您也可以更频繁地重复使用它
public class AccountDetail
{
public string AccountID{get;set;}
public string AccountName {get;set;}
public string AccountDescription {get;set}
public AccountDetail(){}
}
所以查询是:
public static List<AccountDetail> GetDetailedAccounts()
{
return (from a in Db.accounts
join i in Db.financial_institution on a.financial_institution.financial_institution_id
equals i.financial_institution_id
join acct in Db.z_account_type on a.z_account_type.account_type_id equals
acct.account_type_id
orderby i.name
select new AccountDetail
{ AccountID = a.account_id,
AccountName= i.name,
AccountDescription= acct.description}
}).ToList();