为了方面大家更好地理解我写这篇文章的目的,这篇文章我会详细介绍我的代码,我有什么理解错误的,请大家不吝赐教。
首先我定义2 个类。
公司类:
UserCompany.cs
class UserCompany
{
public int ID { get; set; }
public string CompanyName { get; set; }
public string CompanyDesc { get; set; }
}
员工类:
UserInfo.cs
class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public int UserCompanyID { get; set; }
public UserCompany UserCompany_UserCompanyID { get; set; }
}
也许大家看到了,这里的员工类(UserInfo)有一个属性UserCompanyID 来标记这个员工属于哪个公司。
同时也有一个属性UserCompany_UserCompanyID 表示这个UserCompanyID 对应的公司类(UserCompany)。
下面是一个方法来得到所有的公司,一般我们的数据是保存在数据库中的。为了演示,这里就不访问数据库了。
/// <summary>
/// 得到所有的公司信息
/// </summary>
/// <returns></returns>
static IList<UserCompany> GetAllUserCompanys()
{
return new List<UserCompany>()
{
new UserCompany(){ ID = 1, CompanyName = "新浪", CompanyDesc = "新浪是个大公司" },
new UserCompany(){ ID = 2, CompanyName = "百度", CompanyDesc = "百度是个大公司" },
new UserCompany(){ ID = 3, CompanyName = "腾讯", CompanyDesc = "腾讯是个大公司" },
new UserCompany(){ ID = 4, CompanyName = "网易", CompanyDesc = "网易是个大公司" },
new UserCompany(){ ID = 5, CompanyName = "搜狐", CompanyDesc = "搜狐是个大公司" },
new UserCompany(){ ID = 6, CompanyName = "阿里巴巴", CompanyDesc = "阿里巴巴是个大公司" }
};
}
同时也有一个方法来得到所有的员工。
/// <summary>
/// 得到所有的员工信息
/// </summary>
/// <returns></returns>
static IList<UserInfo> GetAllUserInfos()
{
return new List<UserInfo>()
{
new UserInfo(){ ID = 1, UserName = "张三", UserCompanyID = 2 },
new UserInfo(){ ID = 2, UserName = "李四", UserCompanyID = 1 },
new UserInfo(){ ID = 3, UserName = "王五", UserCompanyID = 4 },
new UserInfo(){ ID = 4, UserName = "赵六", UserCompanyID = 1 },
new UserInfo(){ ID = 5, UserName = "杨七", UserCompanyID = 3 },
new UserInfo(){ ID = 6, UserName = "朱八", UserCompanyID = 1 },
new UserInfo(){ ID = 7, UserName = "孙九", UserCompanyID = 2 },
new UserInfo(){ ID = 8, UserName = "萧十一郎", UserCompanyID = 1 }
};
}
一般如果我们得到了所有的员工的基本信息后,还想得到这些员工对应的公司信息,比如:公司名、公司描述等等。
怎么办呢?我的思路是,当我们得到这些员工的基本信息后,就能够得到每个员工对应的公司ID(UserCompanyID),
然后我在利用Linq 取出这些公司ID(UserCompanyID),保存到一个可以枚举的集合中IEnumerable<int>,然后去
数据库中取出这些公司ID(UserCompanyID)对应的公司信息。下面是代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConAppTest
{
class Program
{
static void Main(string[] args)
{
IList<UserInfo> users = GetAllUserInfos();
IEnumerable<int> userCompanyIds = users.Select<UserInfo, int>(u => u.UserCompanyID).Distinct();
IEnumerable<UserCompany> existsCompanys = GetCompanysByCompanyIds(userCompanyIds);
foreach (UserCompany companyItem in existsCompanys)
{
if(companyItem == null)
{
continue;
}
Console.WriteLine(companyItem.CompanyName);
}
}
/// <summary>
/// 得到所有的员工信息
/// </summary>
/// <returns></returns>
static IList<UserInfo> GetAllUserInfos()
{
return new List<UserInfo>()
{
new UserInfo(){ ID = 1, UserName = "张三", UserCompanyID = 2 },
new UserInfo(){ ID = 2, UserName = "李四", UserCompanyID = 1 },
new UserInfo(){ ID = 3, UserName = "王五", UserCompanyID = 4 },
new UserInfo(){ ID = 4, UserName = "赵六", UserCompanyID = 1 },
new UserInfo(){ ID = 5, UserName = "杨七", UserCompanyID = 3 },
new UserInfo(){ ID = 6, UserName = "朱八", UserCompanyID = 1 },
new UserInfo(){ ID = 7, UserName = "孙九", UserCompanyID = 2 },
new UserInfo(){ ID = 8, UserName = "萧十一郎", UserCompanyID = 1 }
};
}
/// <summary>
/// 得到所有的公司信息
/// </summary>
/// <returns></returns>
static IList<UserCompany> GetAllUserCompanys()
{
return new List<UserCompany>()
{
new UserCompany(){ ID = 1, CompanyName = "新浪", CompanyDesc = "新浪是个大公司" },
new UserCompany(){ ID = 2, CompanyName = "百度", CompanyDesc = "百度是个大公司" },
new UserCompany(){ ID = 3, CompanyName = "腾讯", CompanyDesc = "腾讯是个大公司" },
new UserCompany(){ ID = 4, CompanyName = "网易", CompanyDesc = "网易是个大公司" },
new UserCompany(){ ID = 5, CompanyName = "搜狐", CompanyDesc = "搜狐是个大公司" },
new UserCompany(){ ID = 6, CompanyName = "阿里巴巴", CompanyDesc = "阿里巴巴是个大公司" }
};
}
/// <summary>
/// 根据一个或多个CompanyId 得到公司。
/// </summary>
/// <param name="companyIds">一个或多个CompanyId</param>
/// <returns></returns>
static IEnumerable<UserCompany> GetCompanysByCompanyIds(IEnumerable<int> companyIds)
{
IList<UserCompany> companys = GetAllUserCompanys();
foreach (int companyId in companyIds)
{
yield return companys.FirstOrDefault(c => c.ID == companyId);
}
}
}
}
运行结果截图:
如果我们要让这些员工类(UserInfo)的实体属性UserCompany_UserCompanyID 自动指向已经被加载出来的公司实体,怎么办呢?下面有一种方法(完整代码):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConAppTest
{
class Program
{
static void Main(string[] args)
{
IList<UserInfo> users = GetAllUserInfos();
IEnumerable<int> userCompanyIds = users.Select<UserInfo, int>(u => u.UserCompanyID).Distinct();
IEnumerable<UserCompany> existsCompanys = GetCompanysByCompanyIds(userCompanyIds);
foreach (UserCompany companyItem in existsCompanys)
{
if(companyItem == null)
{
continue;
}
Console.WriteLine(companyItem.CompanyName);
}
// 把一个实体类作为属性的引用指向另一个实体类
foreach (UserInfo userItem in users)
{
foreach (UserCompany companyItem in existsCompanys)
{
if (userItem.UserCompanyID == companyItem.ID)
{
userItem.UserCompany_UserCompanyID = companyItem;
break;
}
}
}
// 下面是打印出信息
foreach (UserInfo userItem in users)
{
Console.WriteLine("姓名:" + userItem.UserName + ",公司:" + userItem.UserCompany_UserCompanyID.CompanyName);
}
}
/// <summary>
/// 得到所有的员工信息
/// </summary>
/// <returns></returns>
static IList<UserInfo> GetAllUserInfos()
{
return new List<UserInfo>()
{
new UserInfo(){ ID = 1, UserName = "张三", UserCompanyID = 2 },
new UserInfo(){ ID = 2, UserName = "李四", UserCompanyID = 1 },
new UserInfo(){ ID = 3, UserName = "王五", UserCompanyID = 4 },
new UserInfo(){ ID = 4, UserName = "赵六", UserCompanyID = 1 },
new UserInfo(){ ID = 5, UserName = "杨七", UserCompanyID = 3 },
new UserInfo(){ ID = 6, UserName = "朱八", UserCompanyID = 1 },
new UserInfo(){ ID = 7, UserName = "孙九", UserCompanyID = 2 },
new UserInfo(){ ID = 8, UserName = "萧十一郎", UserCompanyID = 1 }
};
}
/// <summary>
/// 得到所有的公司信息
/// </summary>
/// <returns></returns>
static IList<UserCompany> GetAllUserCompanys()
{
return new List<UserCompany>()
{
new UserCompany(){ ID = 1, CompanyName = "新浪", CompanyDesc = "新浪是个大公司" },
new UserCompany(){ ID = 2, CompanyName = "百度", CompanyDesc = "百度是个大公司" },
new UserCompany(){ ID = 3, CompanyName = "腾讯", CompanyDesc = "腾讯是个大公司" },
new UserCompany(){ ID = 4, CompanyName = "网易", CompanyDesc = "网易是个大公司" },
new UserCompany(){ ID = 5, CompanyName = "搜狐", CompanyDesc = "搜狐是个大公司" },
new UserCompany(){ ID = 6, CompanyName = "阿里巴巴", CompanyDesc = "阿里巴巴是个大公司" }
};
}
/// <summary>
/// 根据一个或多个CompanyId 得到公司。
/// </summary>
/// <param name="companyIds">一个或多个CompanyId</param>
/// <returns></returns>
static IEnumerable<UserCompany> GetCompanysByCompanyIds(IEnumerable<int> companyIds)
{
IList<UserCompany> companys = GetAllUserCompanys();
foreach (int companyId in companyIds)
{
yield return companys.FirstOrDefault(c => c.ID == companyId);
}
}
}
class UserCompany
{
public int ID { get; set; }
public string CompanyName { get; set; }
public string CompanyDesc { get; set; }
}
class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public int UserCompanyID { get; set; }
public UserCompany UserCompany_UserCompanyID { get; set; }
}
}
运行结果截图:
不知道大家注意下面这段代码没有:
foreach (UserInfo userItem in users)
{
foreach (UserCompany companyItem in existsCompanys)
{
if (userItem.UserCompanyID == companyItem.ID)
{
userItem.UserCompany_UserCompanyID = companyItem;
break;
}
}
}
如果我们的很多地方都要实现“把一个实体类作为属性的引用指向另一个实体类”,怎么办呢?难道也是2 层循环,先判断ID 是否相等,然后赋值吗?
我不喜欢写重复的代码,于是想到了委托来简化。下面是代码:
/// <summary>
/// 让指针指向一个实体
/// </summary>
/// <typeparam name="TSource">源实体集合</typeparam>
/// <typeparam name="TValue">值实体集合</typeparam>
/// <param name="sourceItems">源实体集合</param>
/// <param name="sourceValueItems">值实体集合</param>
/// <param name="fn">判断true or false 的委托</param>
/// <param name="actionEvaluate">做一个什么事的委托</param>
static void LetPointerEvaluateEntity<TSource, TValue>(IEnumerable<TSource> sourceItems,
IEnumerable<TValue> sourceValueItems,
Func<TSource, TValue, bool> fn,
Action<TSource, TValue> actionEvaluate)
{
foreach (var sourceItem in sourceItems)
{
foreach (var valueItem in sourceValueItems)
{
if (fn(sourceItem, valueItem))
{
//做一些事,比如:赋值(把一个对象的属性指向另一个对象)
actionEvaluate(sourceItem, valueItem);
break;
}
}
}
}
最后在客户端调用就可以了。完整代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConAppTest
{
class Program
{
static void Main(string[] args)
{
IList<UserInfo> users = GetAllUserInfos();
IEnumerable<int> userCompanyIds = users.Select<UserInfo, int>(u => u.UserCompanyID).Distinct();
IEnumerable<UserCompany> existsCompanys = GetCompanysByCompanyIds(userCompanyIds);
foreach (UserCompany companyItem in existsCompanys)
{
if(companyItem == null)
{
continue;
}
Console.WriteLine(companyItem.CompanyName);
}
// 把一个实体类作为属性的引用指向另一个实体类
/*
foreach (UserInfo userItem in users)
{
foreach (UserCompany companyItem in existsCompanys)
{
if (userItem.UserCompanyID == companyItem.ID)
{
userItem.UserCompany_UserCompanyID = companyItem;
break;
}
}
}
*/
// 把一个实体类作为属性的引用指向另一个实体类(用委托来简化后)
LetPointerEvaluateEntity<UserInfo, UserCompany>(users, existsCompanys,
(user, userCompany) => user.UserCompanyID == userCompany.ID,
(user, userCompany) => user.UserCompany_UserCompanyID = userCompany);
// 下面是打印出信息
foreach (UserInfo userItem in users)
{
Console.WriteLine("姓名:" + userItem.UserName + ",公司:" + userItem.UserCompany_UserCompanyID.CompanyName);
}
}
/// <summary>
/// 得到所有的员工信息
/// </summary>
/// <returns></returns>
static IList<UserInfo> GetAllUserInfos()
{
return new List<UserInfo>()
{
new UserInfo(){ ID = 1, UserName = "张三", UserCompanyID = 2 },
new UserInfo(){ ID = 2, UserName = "李四", UserCompanyID = 1 },
new UserInfo(){ ID = 3, UserName = "王五", UserCompanyID = 4 },
new UserInfo(){ ID = 4, UserName = "赵六", UserCompanyID = 1 },
new UserInfo(){ ID = 5, UserName = "杨七", UserCompanyID = 3 },
new UserInfo(){ ID = 6, UserName = "朱八", UserCompanyID = 1 },
new UserInfo(){ ID = 7, UserName = "孙九", UserCompanyID = 2 },
new UserInfo(){ ID = 8, UserName = "萧十一郎", UserCompanyID = 1 }
};
}
/// <summary>
/// 得到所有的公司信息
/// </summary>
/// <returns></returns>
static IList<UserCompany> GetAllUserCompanys()
{
return new List<UserCompany>()
{
new UserCompany(){ ID = 1, CompanyName = "新浪", CompanyDesc = "新浪是个大公司" },
new UserCompany(){ ID = 2, CompanyName = "百度", CompanyDesc = "百度是个大公司" },
new UserCompany(){ ID = 3, CompanyName = "腾讯", CompanyDesc = "腾讯是个大公司" },
new UserCompany(){ ID = 4, CompanyName = "网易", CompanyDesc = "网易是个大公司" },
new UserCompany(){ ID = 5, CompanyName = "搜狐", CompanyDesc = "搜狐是个大公司" },
new UserCompany(){ ID = 6, CompanyName = "阿里巴巴", CompanyDesc = "阿里巴巴是个大公司" }
};
}
/// <summary>
/// 根据一个或多个CompanyId 得到公司。
/// </summary>
/// <param name="companyIds">一个或多个CompanyId</param>
/// <returns></returns>
static IEnumerable<UserCompany> GetCompanysByCompanyIds(IEnumerable<int> companyIds)
{
IList<UserCompany> companys = GetAllUserCompanys();
foreach (int companyId in companyIds)
{
yield return companys.FirstOrDefault(c => c.ID == companyId);
}
}
/// <summary>
/// 让指针指向一个实体
/// </summary>
/// <typeparam name="TSource">源实体集合</typeparam>
/// <typeparam name="TValue">值实体集合</typeparam>
/// <param name="sourceItems">源实体集合</param>
/// <param name="sourceValueItems">值实体集合</param>
/// <param name="fn">判断true or false 的委托</param>
/// <param name="actionEvaluate">做一个什么事的委托</param>
static void LetPointerEvaluateEntity<TSource, TValue>(IEnumerable<TSource> sourceItems,
IEnumerable<TValue> sourceValueItems,
Func<TSource, TValue, bool> fn,
Action<TSource, TValue> actionEvaluate)
{
foreach (var sourceItem in sourceItems)
{
foreach (var valueItem in sourceValueItems)
{
if (fn(sourceItem, valueItem))
{
//做一些事,比如:赋值(把一个对象的属性指向另一个对象)
actionEvaluate(sourceItem, valueItem);
break;
}
}
}
}
}
class UserCompany
{
public int ID { get; set; }
public string CompanyName { get; set; }
public string CompanyDesc { get; set; }
}
class UserInfo
{
public int ID { get; set; }
public string UserName { get; set; }
public int UserCompanyID { get; set; }
public UserCompany UserCompany_UserCompanyID { get; set; }
}
}
运行结果和上面的代码一样,这个方法让代码简化了很多,是不是呢?您有什么不同的观点,请分享!下面是截图:
代码下载:http://www.2cto.com/uploadfile/2011/1008/20111008034508513.rar