如何在linq中添加条件联接?

时间:2018-12-04 07:47:53

标签: c# linq api

我想根据我传递的参数在linq中添加2个不同的联接。 说“ isHub”是参数。 如果isHub = true:我想返回城市列表 如果isHub = false:我想返回国家列表

这是我当前的查询

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Jquery Ajax File Upload</title>
</head>
<body>

<div class="col-md-12">
   <span id="fileUploadErr">Please Upload A File!</span>
   <div  style="margin-bottom: 10px;"></div>
   <input id="pickUpFileAttachment" type="file" name="pickUpFileAttachment" size="60" />
</div>
    
    <div class="result"></div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script>
    $(document).ready(function(){
   
   //  $("form").submit(function(){
    
        $('#pickUpFileAttachment').change(function(e){
          var formData = new FormData();
formData.append('section', 'general');
formData.append('action', 'previewImg');
// Attach file
formData.append('image', $('input[type=file]')[0].files[0]); 
           
         
            $.ajax({
                url : window.location.pathname + "/form/api/saveProcessAnexTwo",
             data: formData,
    type: 'POST',
    contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
    processData: false, 
                success: function(response){
                 alert("suc");
                    $('.result').html(response.html)
                    
                } , error: function(response){
                        switch(response.status){
                            case 409:
                            alert("error");
                        }}
            });
        });
        //});
    });
    </script>
</body>
</html>

这里要添加这样的联接

   public List<ControlTowerCity> GetControlTowerMapData(bool IsHub)
    {
        using (var context = new LadingControlTowerEntities())
        {
            var mapcityDetail =
            (from SLD in context.ShipmentLocations 
             join CMD in context.CityMasters on SLD.City equals CMD.ID

             select new ControlTowerCity
             { 
                 Name = CMD.Name,

             }).ToList();
            return mapcityDetail;
        }
    }

感谢您的帮助。谢谢

4 个答案:

答案 0 :(得分:3)

using (var context = new LadingControlTowerEntities()) {
    var query = context.ShipmentLocations.AsQueryable();
    // if you have any condition (for example, what you said in comment):
    query = query.Where(t => t.Status == "A");
    IQueryable<ControlTowerCity> resultQuery;
    if (ishHub)
        resultQuery = query.Join(context.CityMasters, t => t.City, t => t.ID, (o, i) => new ControlTowerCity { Name = i.Name });
    else
        resultQuery = query.Join(context.CountryMasters, t => t.Country, t => t.ID, (o, i) => new ControlTowerCity { Name = i.Name });
    var mapcityDetail = resultQuery.ToList();
    return mapcityDetail;
}

答案 1 :(得分:1)

对于此任务,使用method based syntax连接您的IQueryable而不是使用查询语法(例如,参见javad amiry的答案)会更容易,以避免额外的{{1} }和from语句。

但是要回答您的问题:使用查询语法时,您需要将select存储在一个额外的变量中,并在连接上方IQueryable的{​​{1}}部分中使用它再次。

in

答案 2 :(得分:0)

为什么不能有一个/* compile with: c++ -Wall -pedantic -std=c++17 main.cc -lssl -lcrypto -o main */ #include <memory> #include <iostream> #include <openssl/err.h> #include <openssl/pem.h> #include <assert.h> #include <string.h> /* Custom deletors for use with unique_ptr */ struct EVP_PKEY_deleter { void operator()(EVP_PKEY* p) const { if (p) EVP_PKEY_free(p); } }; struct BIO_deleter { void operator()(BIO* p) const { if (p) BIO_free(p); } }; /* Smart pointers wrapping OpenSSL resources */ using evp_key_ptr = std::unique_ptr<EVP_PKEY, EVP_PKEY_deleter>; using bio_ptr = std::unique_ptr<BIO, BIO_deleter>; /* Create key based on memory contents */ evp_key_ptr load_public_key(const char* buf, size_t len) { bio_ptr bp (BIO_new_mem_buf((void*) buf, len)); if (!bp) throw std::runtime_error("BIO_new_mem_buf failed"); EVP_PKEY * kp = nullptr; kp = PEM_read_bio_PUBKEY(bp.get(), &kp, nullptr, nullptr); ERR_print_errors_fp(stderr); return evp_key_ptr{kp}; } int main() { const char * RSA_PUBLIC_KEY=R"( -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA80ZqDPPW5eOH6TWdLsEJ 8qf6hoMJfFZ3BL9Fz+YNGeBpF3zxKmm8UuRrBHHVZZB2Gs1MTo06IU3fqDfFsOyh J6pHeJF3wyUlYZuYbGAyMlZZ/+M5TOvo92f7lt/A40QThCVf1vS5o+V8sFkgnz3N C7+VvC4dYrv+fwnmnWGxPy1qfp3orB+81S4OPRiaoy+cQBZs10KCQaNBI/Upzl2R 3dMkWKM+6yQViKTHavT4DRRZ1MKp9995qOR3XfhhJdWuDl4moXcU3RcX4kluvS5q b8oTnVyd2QB1GkUw6OKLWB/5jN1V1WzeYK447x2h4aPmJfsn5gCFJs6deq2RFQBR SQIDAQAB -----END PUBLIC KEY----- )"; ERR_load_crypto_strings(); ERR_free_strings(); auto pubkey = load_public_key(RSA_PUBLIC_KEY, strlen(RSA_PUBLIC_KEY)); if (pubkey) std::cout << "load_public_key success" << std::endl; } 分支

func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
        if Double(textField.text!) == 0 {
            let alert = UIAlertController(title: "Notice", message: "The input value can't be 0.", preferredStyle: .alert)
            let ok = UIAlertAction(title: "OK", style: .default)
            alert.addAction(ok)

            self.present(alert, animated: false)

            return false
        }
        return true
    }

答案 3 :(得分:0)

我建议创建IQueryable的通用扩展功能。这样,您就可以将它用于需要根据输入变量选择A或B的每个问题。

请参见Extension Methods Demystified

我将创建的扩展功能类似于标准IQueryable.Join

区别在于它具有一个额外的输入布尔参数,而不是一个outerKeySelector,而是两个outerKeySelectorsouterKeySelectorTrueouterKeySelectorFalse

如果Boolean参数为true,我们将使用outerKeySelectorTrue进行联接,否则我们将使用outerkeySelectorFalse进行联接

IQueryable<TResult> Join<TOuter, TInner, TKey, TResult>(
    this IQueryable<TOuter> outer,
    IQueryable<TInner> inner,

    // the boolean to decide which OuterKeySelector to use
    bool isHub,

    // the two KeySelectors: one for true and one for false
    Expression<Func<TOuter,TKey>> outerKeySelectorTrue, 
    Expression<Func<TOuter,TKey>> outerKeySelectorFalse,

    // the rest is standard IQueryable.Join
    Expression<Funt<TInner, TKey>> innerKeySelector
    Expression<Func<TOuter,TInner,TResult>> resultSelector);
{
    return outer.Join(inner,
        // decide which outerKeySelector to use:
        isHub ? outerKeySelectorTrue : outerKeySelectorFalse, 

        // the rest is as in a standard join:
        innerKeySelector,
        resultSelector);
}

仅此而已!我们所需要的只是一个类似于已有连接的函数声明,以及一条使用externalKeySelectorTrue或externalKeySelectorFalse

调用此已有连接的语句。

用法

标准加入

var result = dbContext.ShipmentLocations         // join ShipmentLocations
    .Join(dbContext.CityMasters,                 // with CityMasters
    shipmentLocation => shipmentLocation.CityId, // from ShipmentLocation take foreign key CityId
    cityMaster => cityMaster.Id,                 // from CityMaster take the primary key Id
    (shipmentLocation, cityMaster) => new        // when they match, make one new object
    {
        // select only the properties you plan to use
        Name = shipmentLocation.Name,
        Location = cityMaster.City,
        ...
    });

扩展加入

我们有两个outerKeySelector,而不是一个outerKeySelectors,其余的等于标准联接

bool isHub = ...
var result = dbContext.ShipmentLocations         // join ShipmentLocations
    .Join(dbContext.CityMasters,                 // with CityMasters

    // the boolean that decides which of the two outerKeySelectors to use
    isHub,                                       

    // the two outerKeySelectors: one for isHub true and one for isHub fale
    shipmentLocation => shipmentLocation.City,
    shipmentLocation => shipmentLocation.Country,

    // the innerKeySelector: used to compare with the selected outerKey
    cityMaster => cityMaster.Id,

    (shipmentLocation, cityMaster) => new        // when they match, make one new object
    {
        // select only the properties you plan to use
        ...
    });

令人高兴的是,它可以与所有IQueryable一起使用,无论它们是ShipmentLocations和CityMasters,还是拥有学生的学校,拥有订单的客户等。

此外,它与LINQ的用法非常相似,并且只有一条语句