eol*_*dre 5 linq extension-methods encapsulation linq-to-sql
给出了LINQ to SQL .dbml文件中的两个类,具有以下特性.
Customer
CustomerId
FirstName
LastName
AddressId
Address
AddressId
Street
City
State
Zip
Run Code Online (Sandbox Code Playgroud)
您可以构造一个LINQ查询,如下所示.
using(var db = new MyDataContext())
{
results = db.Customers
.Where(c => c.LastName.BeginsWith("o"))
.Select(c => new
{
c.CustomerId,
MailingAddress = c.FirstName + " "
+ c.LastName
+ Environment.NewLine
+ c.Address.Street
+ Environment.NewLine
+ c.Address.City + ", "
+ c.Address.State + " "
+ c.Address.Zip
}).ToList();
}
Run Code Online (Sandbox Code Playgroud)
现在让我们说你想要解释邮件地址的逻辑.您可以实现的两种方法是向Customer类添加新属性,或创建扩展方法.
public static class CustomerExtensions
{
public static string GetMailingAddress(this Customer cust)
{
return cust.FirstName + " "
+ cust.LastName
+ Environment.NewLine
+ cust.Address.Street
+ Environment.NewLine
+ cust.Address.City + ", "
+ cust.Address.State + " "
+ cust.Address.Zip;
}
}
public partial class Customer
{
public string MailingAddress
{
get
{
return this.FirstName + " "
+ this.LastName
+ Environment.NewLine
+ this.Address.Street
+ Environment.NewLine
+ this.Address.City + ", "
+ this.Address.State + " "
+ this.Address.Zip;
}
}
}
Run Code Online (Sandbox Code Playgroud)
你现在可以使用其中一个,你会得到正确的结果
using(var db = new MyDataContext())
{
results = db.Customers
.Where(c => c.LastName.BeginsWith("o"))
.Select(c => new
{
c.CustomerId,
c.MailingAddress, //new property
Address2 = c.GetMailingAddress() // new extension method
}).ToList();
}
Run Code Online (Sandbox Code Playgroud)
这两种方法的问题在于,这样做会导致为您检索的每一行进行额外的数据库往返.初始查询将从Customer表中提取信息,然后在评估邮件地址时需要单独评估每个地址记录.
有没有办法封装这个逻辑并将其绑定到客户类,以便您不需要额外的数据库往返?
我认为必须有一些方法来创建一个扩展方法,而不是返回一个表达式而不是字符串.我对吗?如果是这样,我该怎么做?
我知道这并不完全是您想要的,但您可以这样做:
var options = new DataLoadOptions();
options.LoadWith<Customer>(c => c.Address);
db.LoadOptions = options;
Run Code Online (Sandbox Code Playgroud)
然后,当客户检索地址时,它只会进行一趟。