如何编写linq到sql属性的表达式?

时间:2009-01-31 12:51:10

标签: linq-to-sql

我对这个冗长的问题提前做出了批评。我努力让我的问题尽可能清楚地一目了然。请多多包涵。 ; o)非常感谢任何帮助!

我有类分支和文字:

class Branch
 int ID
 Text WebDescription
 and a bunch of other properties

class Text
 int ID
 string UK
 string NL
 string FR
 string IT
 and a bunch of other properties as well

我想只以适当的语言显示分支的ID及其描述。我只想要一个查询(没有额外的往返)只检索两个字段(不是整个对象)。

我找到了三个解决方案

通过查询中的对象模型

// good: no round trips
// good: clean sql
// bad:  impossible to use the currentUserLanguage parameter
var lang = "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
            select new
               {
                 b.ID,
                 WebDescription = b.WebDescriptionObject.NL // <-- problem
               };
var text = query.First().WebDescription;

查询后通过对象模型

// good: no round trips (eager loading of text object)
// good: possible to use the currentUserLanguage parameter
// bad:  loads the *whole* branch and text object, not just two fields
var lang= "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
            select new
              {
                b.ID,
                WebDescription = b.GetWebDescriptionAsString(lang)
              };
var text = query.First().WebDescription;

使用表达式

// good: I have the feeling I am on the right track
// bad: This doesn't work :o( throws an exception
var lang= "NL";
var dbProject = new ProjectDataContext();
var query = from b in dbProject.GetTable<Branch>()
            select new
              {
                b.ID,
                WebDescription = b.GetWebDescriptionAsExpression(lang)
              };
var text = query.First().WebDescription;

以下是两个方法GetWebDescriptionAsString和GetWebDescriptionAsExpression的代码。

public string GetWebDescriptionAsString(string lang)
{
  if (lang== "NL") return WebDescriptionObject.NL;
  if (lang== "FR") return WebDescriptionObject.FR;
  if (lang== "IT") return WebDescriptionObject.IT;
  return WebDescriptionObject.UK;
}

public Expression<Func<Branch, string>> GetWebDescriptionAsExpression(string lang)
{
  if (lang== "NL") return b => b.WebDescriptionObject.NL;
  if (lang== "FR") return b => b.WebDescriptionObject.FR;
  if (lang== "IT") return b => b.WebDescriptionObject.IT;
  return b => b.WebDescriptionObject.UK;
}

5 个答案:

答案 0 :(得分:1)

如果没有真正回答这个问题,最干净的方法是将文本结构更改为更加规范化的形式,如:

Text
    ID

TextTranslation
    ID
    TextID
    Lang
    TextValue

其中每个文本都有多个翻译,每种语言一个。

查询将变为:

var q = 
    from branch in dbProject.Branches
    join text in dbProject.Texts on branch.TextID = text.ID
    join translation in dbProject.TextTranslations on text.ID = translation.TextID
    where translation.Lang == lang
    select new
    {
        branch.ID,
        WebDescription = translation.TextValue
    };

这种方法也有其他优点,例如添加新语言不会改变模型结构。

答案 1 :(得分:0)

如果您使用存储过程,这将非常容易。您是否反对使用SP作为解决方案?

答案 2 :(得分:0)

如果存储过程有效,那么我很乐意使用它。

答案 3 :(得分:0)

不了解你的整个问题

创建一个这样的存储过程:

CREATE PROCEDURE spGetTheTextINeed @Language char(2), @BranchID int
AS
  /* I don't know how your database is structured so you need to write this */
  SELECT MyText from MyTable WHERE Language=@Language and Branch=@BranchID


然后你需要将sp添加到DBML中,然后你可以用适当的参数调用你需要的sp:

var query = myDataContext.spGetTheTextINeed("NL",[your branch number]) 

  Dim str As String 
  str = query.MyText 

上面的代码并不准确 - 我不明白你的全部要求,但这应该让你开始。

答案 4 :(得分:0)

感谢您的及时回复。

我做了一个快速的尝试。 UDF已经存在,我只是不知道如何使用它。表现明显下降。第一种解决方案快3倍。据我了解,这种方法需要额外往返数据库。这是对的吗?

var query = from b in dbProject.GetTable<Branch>()
            select new
              {
                b.ID,
                WebDescription = db.fGetText(b.WebDescriptionID, (currentUserLanguage))
              };