簡體   English   中英

帶有匿名類/屬性的LINQ

[英]LINQ with anonymous class/properties

我正在將一個項目從使用標准數據庫查詢轉移到使用EF和LINQ。 我有一個表,其中包含某些記錄,這些記錄可用於構建類似於以下內容的查詢:

select * from client where city = ?

在我的原始表中,我將從表中提取客戶端和城市以構建該查詢。

上面的客戶和城市也可能是另一個表和/或字段。 我將如何使用EF和LINQ做同樣的事情? 這是否有可能,還是我必須建立一個單獨的類來處理所有這些邏輯?

var query = from c in context.clients
            where c.city == ?
            select c;

編輯:這不是關於加入查詢。 這是關於構建動態查詢的。 我不知道我在運行程序時是否要查詢城市,地址,甚至查詢“客戶”表本身。 它可能在另一張桌子上。 我希望能夠動態構建查詢。

如果您的表是通過外鍵聯接的,則可以使用LINQ如下訪問另一個表中的值。 (我通過假設有一個“地址”表和clients表具有外鍵來擴展您的示例。)

var query = from c in context.clients
            where c.address.city == ?
            select c;

編輯:(試圖了解您的原始問題和后續評論...)

您要問的是您是否可以做這樣的事情?

string cityName = "Los Angeles"; // Could be a parameter, etc.

var query = from c in context.clients
            where c.city == cityName
            select c;

或者,比您的問題更進一步,也許是這樣的:

string cityName = (from c in context.cities
                   where c.id == 5
                   select c.name).FirstOrDefault();

var query = from c in context.clients
            where c.city == cityName
            select c;

由於它是一個IQueryable,因此您也可以隨時添加其他條件。

if (someCondition)
{
    query = from q in query
            where q.someField >= conditionValue
            select q;
}

管他呢。 在實際需要結果之前,不會真正評估/執行查詢表達式樹。

您可以編寫由GalacticCowboy提出的查詢,例如

var query = from c in context.clients
        join add in context.Addresses on c.AddressID equals add.AddressID
        where addr.city == ?
        select c;

這兩個查詢都將生成內部聯接,性能沒有差異。 唯一的區別是,如果Address對於客戶端是可選的,則c.address.City將向沒有地址的客戶端拋出異常,而此查詢將返回一個空的枚舉

如果您確實想在運行時構建查詢,則有幾種基於linq的解決方案可用-您可以在運行時將代碼編譯為臨時程序集,也可以使用MS示例之一中的DynamicLinq。

有關更多信息,請參見以下問題和解答: 如何從字符串創建LINQ查詢?

我認為您可以采取幾種方法。

首先,您可以研究Dynamic LINQ庫 (也可以在此處查看David Fowler的更新)。 使用這種方法,您可以這樣編寫LINQ查詢:

var results = Context.Clients
                .Where("city=='Los Angeles'")
                .OrderBy("address");

因此,您的WhereOrderBy謂詞是可以Where OrderBy轉換為Expressions的字符串。

其次,如果您知道要查詢的內容,但不確定是否要查詢一個或多個字段,則可以使用PredicateBuilder之類的庫,例如:

var predicate = PredicateBuilder.True<Clients>();
foreach(var criteria in searchCriteria) {
  if (criteria.Key=="city"){
    predicate = predicate.And(c => c.city==criteria.Value);
  } else if (criteria.Key=="address"){
    predicate = predicate.And(c => c.address==criteria.Value);
  }
}
var results = Context.Clients.Where(predicate);

第三,也許是最困難的,是構建自己的表達式樹。 這肯定需要最多的代碼(起初有點深),但是它非常非常強大。 來自MSDN的該示例很好地介紹了您可以做什么(可能比我在這里做得更簡潔)。

因此,基本上,您可以使用一些選擇。 動態LINQ庫似乎是最易於使用的,但是我從未使用過,所以我不能肯定地說它的工作原理和可靠性。 如果有幫助的話,還有一個用於動態LINQ庫的NuGet軟件包。

祝好運。 希望這可以幫助!

如果要在Entity Framework中構建動態查詢,則可能會遇到嘗試動態構建表達式樹的麻煩。 但是,實體框架為您提供了一些其他選項。

首先,EntityObject還有一些其他的對象服務方法,這些方法已經使您可以構建字符串並將其直接傳遞給多個謂詞,包括Where:

c.Customers.Where("City = 'London'");

如果您需要構建更大的查詢,包括動態設置查詢源,請考慮使用EntitySQL。 例如,對於EntitySQL,您可以使用簡單的字符串解析並生成如下代碼:

string entitySQL = "SELECT VALUE c FROM Customers AS c WHERE c.Address.City = 'Seattle';";
ObjectQuery<Customer> query = context.CreateQuery<Customer>(entitySQL);

您可以在Entity Framework Query Samples中看到這兩個選項的實際作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM