[C#] LINQ Condition

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • XiniX88
  • Registratie: December 2006
  • Laatst online: 11-09 06:58
Probleem
Heb de volgende filter voor IQToolkit (LINQ to SQL):
Plaksel 1:
C#:
1
2
3
4
5
6
7
8
9
var languageCondition = (
    from ll in tables.Languages()
    where ll.LanguageName == "Dutch"
    select ll.LanguageId).ToArray();

Expression<Func<IEnumerable<Entities.Person>, IEnumerable<Entities.Person>>> _
    mijnExpressie = p => from pp in p 
    where languageCondition.Contains(pp.LanguageId) 
    select pp;


Deze kan vervolgens bovenop IQToolkit gezet worden, zodat uit de personentabel alleen de mensen worden gehaald die nederlands spreken (in dit voorbeeld).

De conditie geld voor alle SELECT statements, maar ik wil graag dat UPDATE en DELETE statements ook langs deze expressie gaan. Een persoon is in dit geval dan alleen gerechtvaardigd om SELECT, UPDATE en DELETE uit te voeren op nederlands talige gebruikers.

Nu de vraag, ik heb een Person object, like:
C#:
1
2
3
4
var person = new Entities.Person();
person.Firstname = "Een naam";
person.Lastname = "Iets anders";
person.LanguageId = 8;


Dit wil ik valideren met bovenstaande expressie.

Wat heb ik geprobeerd:
  1. De where clause los te trekken, echter IQToolkit wil het vertalen naar SQL, en ziet een Userfunction staan als where clause, iets wat hij niet kan vertalen, in ieder geval niet op de volgende manier:
    C#:
    1
    2
    3
    4
    
    Expression<Func<IEnumerable<Entities.Person>, IEnumerable<Entities.Person>>> _
        mijnExpressie = p => from pp in p 
        where mijnCheckFunctie(pp.LanguageId) // <--- Niet mogelijk
        select pp;
  2. Een list van mn te update'n object te maken, en deze in de Expressie zetten, zodat ik alleen de UPDATE objecten terugkrijg die mogen worden gedaan, echter bij een Func zou dit gaan met:
    C#:
    1
    2
    
    // mijnExpressie komt uit "Plaksel 1"
    var nieuweList = mijnExpressie(listVanPersons); 

    Een dergelijke constructie zou leuk zijn, BatchUpdate zou dan ook behoren tot de mogelijkheid. Echter van een Func maak je geen expression [url=http://stackoverflow.com/questions/767733/converting-a-net-funct-to-a-net-expressionfunct](bron)[/.
Mogelijke oplossingen:
  • List maken en deze door de select expressie laten gaan, zodat je alleen objecten terug krijgt die geupdate mogen worden, echter ik heb geen idee hoe dit te doen met een Expression<Func<,>>
  • De where clause loskoppelen en dan de list (met updateble objects) met deze where clause valideren (.Where(Expression<>)), echter moet dit compatible zijn met IQToolkit, en deze kan geen user functions omzetten (wel Array's of Expressies)
  • ...
Mijn leesvoer is geweest:
[list]• http://tomasp.net/blog/dynamic-linq-queries.aspx
http://blogs.msdn.com/b/m...rate-dynamic-methods.aspx
http://msdn.microsoft.com/en-us/library/bb397951.aspx


Gebruikte software:
[list]• IQToolkit

Wie o wie kan mij op weg helpen?

[ Voor 4% gewijzigd door XiniX88 op 18-03-2011 09:21 ]


Acties:
  • 0 Henk 'm!

  • Guldan
  • Registratie: Juli 2002
  • Laatst online: 11-09 19:49

Guldan

Thee-Nerd

kan je misschien een database design geven? Het is mij niet helemaal duidelijk. Want je kan toch gewoon joinen op die andere tabel?

You know, I used to think it was awful that life was so unfair. Then I thought, wouldn't it be much worse if life were fair, and all the terrible things that happen to us come because we actually deserve them?


Acties:
  • 0 Henk 'm!

  • XiniX88
  • Registratie: December 2006
  • Laatst online: 11-09 06:58
Guldan schreef op vrijdag 18 maart 2011 @ 09:52:
kan je misschien een database design geven? Het is mij niet helemaal duidelijk. Want je kan toch gewoon joinen op die andere tabel?
Laat je niet misleiden door de language select. Dit is een cache, als ingelogde user kunnen delen van de condition worden gecached. Waar het mij om gaat is dat ik geen idee heb hoe ik iets met de Expression kan, of hoe ik een where clause kan maken en appenden zonder dat het een UserExpression is.

Relevant voor dit voorbeeld:
code:
1
2
3
4
5
6
7
Languages       |  Persons            |
----------------|  -------------------|
LanguageId      |  PersonId           |
LanguageName    |  LanguageId         |
________________|  PersonFirstname    |
                   PersonLastname     |
                   ___________________|


Wat ik probeer:
C#:
1
var query = from p in tables.Persons() select p;


In "Plaksel 1" (post 1) heb ik een expressie die ik doorgeef aan IQToolkit, waardoor die automatisch alleen personen selecteerd met de taal Dutch.

Dezelfde expressie wil ik gebruiken voor het gebruiken voor het doen van updates. Een gebruiker mag dus alleen personen aanpassen die LanguageName dutch hebben.

C#:
1
2
3
4
5
6
var person = new Entities.Person();
person.PersonId = 1;
person.Firstname = "Een naam"; 
person.Lastname = "Iets anders"; 
person.LanguageId = 8;
tables.Persons().Update(person)


Wat ik dan dus wil is dat in de Update function de expressie (Plaksel 1) hierop uitvoeren, en kijken of de gebruiker deze persoon wel mag updaten.

Mijn bovenstaande expressie zegt:
C#:
1
where languageCondition.Contains(pp.LanguageId) 

Daar moet het object dus aan voldoen om te mogen updaten. Alleen de vraag is, hoe ga ik dit testen, waarbij ik de code niet 2 keer wil tiepen, maar eigenlijk Plaksel1, "mijnExpressie" wil gebruiken, of de where clause van "mijnExpressie" opdelen in een andere functie

Pseudocode:
C#:
1
2
3
4
5
6
7
8
9
Expression<Func<IEnumerable<Entities.Person>, IEnumerable<Entities.Person>>> _ 
    mijnExpressie = p => from pp in p  
    where mijnFunctie(pp.LanguageId)
    select pp

public bool mijnFunctie(Person persoon)
{
    return languageCondition.Contains(pp.LanguageId);
}


Alleen mijnFunctie kan hier niet worden gebruikt.

Het is de bedoeling overigens dat je meerdere condities hebt, die niet vooraf bekend zijn en over een query worden gezet (SELECT) en bij UPDATE wordt gekeken of je dus ook die permissies wel hebt.

Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 11-09 14:44
Kijk eens hier naar Coding Glamour: Zoekscherm dat dynamisch queries maakt met Expression Trees en MVC

Bedoeling is dus dat je geen functies kan hebben die bool teruggeven, want dan zou je C# code moeten draaien tijdens je SQL code. Je moet altijd een IQueryable hebben; want die kan vertaald worden. Iets als:

C#:
1
2
3
public IQueryable<Person> mijnFunctie(IQueryable<Person> persoon) {
     return persoon.Where(p=>p.languageCondition.Contains(pp.LanguageId));
}

[ Voor 7% gewijzigd door creator1988 op 18-03-2011 11:20 ]


Acties:
  • 0 Henk 'm!

  • XiniX88
  • Registratie: December 2006
  • Laatst online: 11-09 06:58
creator1988 schreef op vrijdag 18 maart 2011 @ 11:19:
Kijk eens hier naar Coding Glamour: Zoekscherm dat dynamisch queries maakt met Expression Trees en MVC

Bedoeling is dus dat je geen functies kan hebben die bool teruggeven, want dan zou je C# code moeten draaien tijdens je SQL code. Je moet altijd een IQueryable hebben; want die kan vertaald worden. Iets als:

C#:
1
2
3
public IQueryable<Person> mijnFunctie(IQueryable<Person> persoon) {
     return persoon.Where(p=>p.languageCondition.Contains(pp.LanguageId));
}
Mijn dank is groot!

Sorry voor het late antwoord, ik was er gedurende de dag al vollop mee bezig, precies wat ik zoek.