C#,LINQ,SQL:复合列

3

我有一个LINQ实体,需要创建一个特殊的字符串值。它由7个不同的值用“-”分隔而成。其中一些字段在该表中使用,而另一些字段在其他表中使用。我希望以某种方式将此字段添加到实体中,以便每次需要时无需自己创建此字符串。

我想可以通过像这样的部分类将其添加到实体中:

    public string SpecialField
    {
        get
        {
            return string.Format("{0}-{1}-{2}-{3}-{4}-{5}-{6}",
                                 TableId,
                                 Number,
                                 ForeignTableA.Date,
                                 ForeignTableB.Name,
                                 ForeignTableC.ForeignTableD.Name,
                                 ForeignTableB.ForeignTableE.Name,
                                 ForeignTableB.Number ?? 0);
        }
    }

然而,在写下这句话之后,我有点不确定它是否有效。因为,除非我错了,否则每次使用该值时都会导致数据库查询所有项目。并且,例如在Where子句中使用该字段是否有效呢?

我需要在Where子句中使用该字段,并希望它发生在服务器上,这样我就不会获取更多的数据。

您应该如何最好地做到这一点?

3个回答

2
您可以在数据库中创建一个视图来处理这个问题。这样,SQL Server会负责它,并且您可以更有效地查询它。

你能在视图中使用外键吗?这样我就可以在我的Linq实体中获得1对1的关系了。 - Svish
不确定我完全理解你的问题。是的,您可以在视图中包含外键列,以便与其他数据关联,但是关系始终强制执行在表上而不是在视图上。 如果您想要从其他数据中进行某种查找,那么这将起作用,但它仍然不能最佳地执行。如果可能的话,我会将所有需要此请求的数据放入该视图中,并仅查询视图。 - Jonathan van de Veen

1

我认为你需要使用带有匿名类型的let子句。虽然我没有测试过,但是类似下面这样的代码可能会起到作用:

var query = from master in MasterTable
            join foreignA in ForeignTableA on ...
            join foreignB in ForeignTableB on ...
            let special = string.Format ("...", master.TableID, ...)
            where special.Contains ("foo")
            select { 
                 // ...
                 string specialResult = special,
                 // ...
            }

但这是在查询本身中完成的,这意味着我需要将 let special = string.Format(... 添加到每个需要它的查询中。这有点烦人,特别是如果它需要更改。 - Svish
你可以将实际格式放在一个方法中:让special = ComputeSpecial(master, foreignA, foreignB)。如果您正在将外部对象的引用存储在主对象中,您始终可以使用这些引用。但是您需要以某种方式获取外部行的实际内容。如果您想让服务器完成所有操作,则需要存储过程;我对存储过程一点也不熟悉。 - XXXXX
你绝对可以在LINQ查询中调用某些函数;我不确定可能存在哪些限制。我经常使用它们,而且我没有遇到任何反直觉的问题。 - XXXXX

0
你读取一次后缓存这个值怎么样?虽然不像一次性获取所有值那样高效,但它可以防止多次尝试获取相同的值。(当然,这仅适用于在使用过程中SpecialField内容不会更改的情况。)
protected string specialField = null;

public string SpecialField
{
    get
    {
        if (specialField == null)
        {
            specialField = string.Format("{0}-{1}-{2}-{3}-{4}-{5}-{6}",
                             TableId,
                             Number,
                             ForeignTableA.Date,
                             ForeignTableB.Name,
                             ForeignTableC.ForeignTableD.Name,
                             ForeignTableB.ForeignTableE.Name,
                             ForeignTableB.Number ?? 0);
        }
        return specialField;
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接