linq - 通过扩展方法在 linq to sql 查询中封装逻辑

标签 linq linq-to-sql extension-methods encapsulation

在您的 LINQ to SQL .dbml 文件中给定两个具有以下属性的类。

Customer
    CustomerId
    FirstName
    LastName
    AddressId

Address
    AddressId
    Street
    City
    State
    Zip

您可以构造如下所示的 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();

}

现在假设您想说明将邮寄地址放在一起的逻辑。您可以通过两种方法来实现这一点,即向 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;
        }
    }
}

你现在可以使用其中之一,你会得到正确的结果
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();

}

这两种方式的问题在于,这样做会导致您检索的每一行都需要额外的往返数据库。初始查询将从 Customer 表中提取信息,然后在评估邮寄地址时需要单独对每个地址记录进行评分。

有没有办法封装这个逻辑并将其与客户类联系起来,这样您就不需要任何额外的数据库往返行程?

我认为必须有某种方法来创建一个扩展方法,而不是返回一个表达式而不是一个字符串。我对吗?如果是这样,我该怎么做?

最佳答案

我知道这不是您正在寻找的,但您可以这样做:

var options = new DataLoadOptions();
options.LoadWith<Customer>(c => c.Address);
db.LoadOptions = options;

然后它只会进行一次旅行,因为地址是与客户一起检索的。

关于linq - 通过扩展方法在 linq to sql 查询中封装逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3935237/

相关文章:

c# - HtmlHelper 扩展的动态

c# - 如果选择的值为空,如何让我的 Linq 选择返回值?

c# - LINQ 按 x 天数分组

C# Linq - 连接具有多个字段的表时出现问题 - 错误 CS1941

sql-server - LINQ To SQL 表示读取器关闭时调用 Read 的尝试无效

c# - 客户关系管理 2011 : Limitation of query expression?

c# - 有没有更好的方法将对象从数据库查询映射到对象?

c# - linq to xml 中标记的内容

c# - 使用 Linq to SQL 自定义实现 DomainService

c# - 接口(interface)扩展方法,具有匹配的通用参数