Как использовать функцию instr () с аргументами типа столбца в Spark

Причина, по которой первый сценарий не работает, заключается в том, что System.Linq.IQueryable является интерфейсом, который реализуется, среди прочих, классом System.Data.Entity.DbSet. В C #, если класс C реализует интерфейс I, когда дело доходит до переходов между типами, вы можете также рассматривать I как базовый класс C (даже семантика class C : I предлагает такой подход) , И поскольку вы не можете неявно (то есть не дословно) использовать класс (или интерфейс) для одного из его классов-потомков, вы получаете ошибку времени компиляции при попытке сделать это. Вы можете сделать обратное, то есть неявно применить класс потомков к его базовому классу (или интерфейсу). Это то, что происходит во втором сценарии.

В вашем случае вы можете обмануть компилятор, произнеся явно:

query = (DbSet<Customer>) query.Where(p => p.Id == id);

, но я бы настоятельно советовал вам не с тех пор, ll заканчивается беспорядочным исключением, потому что результат query.Where(p => p.Id == id) на самом деле не является экземпляром DbSet<Customer>, а скорее некоторым классом, представляющим результат запроса, выполненного на DbSet<Customer>, который реализует интерфейс IQueryable .

Итак, чтобы подвести итог, давайте рассмотрим все сценарии:

Сценарий 1:

//query is of type DbSet<Customer>
var query = _db.Products; 
if (bool) {
  //here you're trying to assign a value of type IQueryable<Customer>
  //to a variable of it's descendant type DbSet<Customer>
  //hence the compile-time error
  query = query.Where(p => p.Id == id); 
}

Сценарий 2:

//here you implicitly cast value of type DbSet<Customer>
//to IQueryable<Customer>, which is OK
IQueryable<Customer> query = _db.Products; 
if (bool) {
  //here you're assigning a value of type IQueryable<Customer>
  //to a variable of the same type, which is also OK
  query = query.Where(p => p.Id == id); 
}

Сценарий 3:

//I assume you have the following line in your code
var products = _db.Products;
//query is of type IQueryable<Customer>, because you perform
//a query on the DbSet<Product>
var query = from product in products
            select product;
if (bool) {
  //here you're assigning a value of type IQueryable<Customer>
  //to a variable of the same type, which is OK
  query = query.Where(p => p.Id == id); 
}
0
задан Mrgr8m4 13 July 2018 в 08:25
поделиться

1 ответ

instr не предназначен для использования так, как вы хотите его использовать, но вы всегда можете попробовать определить udf для выполнения задания:

scala> val instr2_ : (String, String) => Int = (str, sub) => str.indexOfSlice(sub)
// instr2_: (String, String) => Int = <function2>

scala> val instr2 = udf(instr2_)
// instr2: org.apache.spark.sql.expressions.UserDefinedFunction = UserDefinedFunction(<function2>,IntegerType,Some(List(StringType, StringType)))

scala> df.withColumn("KOL3", instr2($"KOL2",$"KOL1")).show
// +----+---------+----+
// |KOL1|     KOL2|KOL3|
// +----+---------+----+
// | 123|940932123|   6|
// | 940|123940932|   3|
// | 932|940123932|   6|
// +----+---------+----+
0
ответ дан eliasah 17 August 2018 в 13:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: