2009-09-21 62 views
3

我有一个LINQ实体,我需要为其创建一个特殊的字符串值。它是由“ - ”分隔的7个不同值。一些使用的字段在该表中,而其中一些使用不同的表。我想以某种方式将该字段添加到实体中,以便在我每次需要时都不必自己创建该字符串。C#,LINQ,SQL:复合列

我想我可以把它像这样一个局部类添加到实体:

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子句中使用该字段,并且我希望它在服务器上发生,所以我不会获取比我需要的更多数据。

你最好怎么做?

回答

2

你可以在数据库中创建一个视图这个给你。这种方式SQL Server照顾它,你可以更有效地查询

+0

你可以在视图中有外键,所以我可以在我的linq实体或其他东西中获得一对一的关系吗? – Svish 2009-09-21 19:08:33

+0

不知道我是否完全理解你的问题。是的,您可以在视图中包含外键列,以便与其他数据关联,但是关系始终在表格上执行,而不是在视图上执行。 如果您想从其他数据中进行某种查找,那么这种方法可以正常工作,但仍然无法达到最佳状态。如果可能的话,我会将该请求所需的所有数据放在该视图中,并仅查询该视图。 – 2009-09-22 06:37:56

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, 
       // ... 
      } 
+0

但这是在查询本身,这意味着我必须补充一点,做'让特殊=的String.format (...)对于每一个需要它的查询,哪一种会很烦人,特别是如果它需要改变的话 – Svish 2009-09-21 10:16:54

+0

你可以把实际的格式放在一个方法中:let special = ComputeSpecial(master,foreignA,foreignB) 如果您在主对象中存储对外部对象的引用,您可以始终使用这些对象,但您需要以某种方式获取外部行的实际内容 如果您想让服务器执行所有操作, AFAIK你需要一个存储过程;不过,我并不擅长存储过程。 – XXXXX 2009-09-21 12:09:25

+0

@Larry:我不确定,但我认为不支持调用你自己的方法... – ShdNx 2009-09-21 14:38:42

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; 
    } 
}