Domanda

Ho uno strano problema durante l'eliminazione dei record usando linq, il mio sospetto è che abbia qualcosa a che fare con la variabile range (chiamata source). Dopo aver eliminato un record, tutte le destinazioni per un cliente vengono recuperate utilizzando la seguente dichiarazione:

var q = from source in unitOfWork.GetRepository<db_Target>().Find()
  where source.db_TargetBase.db_Person.fk_Customer == customerID
  select source.FromLinq();

dove FromLinq è nel metodo di estensione su db_target:

public static Target FromLinq(this db_Target source)
{
    return new Target
    {
        id = source.id,
        LastModified = source.db_TargetBase.LastModified,
        ...
     }
}

Quando un record viene eliminato sia db_Target che db_TargetBase vengono eliminati. Quando, ad esempio, due utenti stanno eliminando record, linq tenta di recuperare un record per user2 che viene eliminato dall'utente1, causando un arresto anomalo sulla linea LastModified = source.db_TargetBase.LastModified perché null è return new Target.

Quando si utilizza il seguente codice il problema non si verifica e vengono recuperati solo i record non eliminati:

var q = from source in unitOfWork.GetRepository<db_Target>().Find()
    where source.db_TargetBase.db_Person.fk_Customer == customerID
    select new Target
    {
        id = source.id,
        LastModified = source.db_TargetBase.LastModified,
        ...
    };

Questo genera due domande:

  1. Cosa sta succedendo qui? Sto facendo una copia della variabile di intervallo <=> perché la sto usando in un metodo di estensione?
  2. Come posso " avvolgere " il <=> codice? Lo sto usando in più punti e non voglio copiarlo ogni volta. Rendere il mio codice più difficile da mantenere.

TIA,

JJ

È stato utile?

Soluzione

Nel primo set di codice - poiché l'inizializzatore utilizza un metodo non traducibile (estensione o altro), non può essere tradotto - quindi viene eseguito localmente.

Nel secondo set di codice, l'inizializzatore è rappresentato da un'espressione elementinit, che viene tradotta (esaminare / confrontare la clausola select del sql generato per la prova).


se vuoi concludere questo, devi avere un Expression<Func<db_Target, Target>> che chiunque possa prendere e usare nella sua query. Fortunatamente, è facile da fare:

public Expression<Func<db_Target, Target>> GetFromLinqExpressionForTarget()
{
  return
    source => new Target
    {
      id = source.id,
      LastModified = source.db_TargetBase.LastModified,
      ...
    }
}

Che può essere usato in questo modo:

var FromLinq = GetFromLinqExpressionForTarget();
var q =
(
   from source in ...
   ...
   ...
   select source
).Select(FromLinq);

Ora ... sto davvero provando a indovinare qui e sono solo circa il 60% sicuro che la mia risposta sia corretta. Quindi, se qualcuno vuole confermarlo, questo renderà la mia giornata. :)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top