1

Konu: Yine Linq

dim db as new dataclassesdatacontext

dim query = from q  in db.bankalar where a=b and c=d select q

query tablosunun boş olduğunu nasıl test edebilirim.

if query.count > 0 .....

if query.single() ....

Bunlar Hata döndürüyor.

if query is nothing ...

kayıt dönmediğini bildiğim halde varmış gibi davranıyor.

Internette epey aradım. Ama çalışan bir çözüm bulamadım. Yardımcı olacak arkadaş varmı ?

2

Re: Yine Linq

Ne hatasi veriyor? O a, b ... de bir sorun var herhalde. Bu bende hata vermiyor:

C#
Sub Main

    dim query = from c in Customers where c.Country = "NO WHERE" select c
  if query.count > 0
  Console.WriteLine("OK")
  else
  Console.WriteLine("Not OK")
    end if
End Sub

3 Son düzenleyen, Aligocmen (26.10.2010 21:12:07)

Re: Yine Linq

Selam Çetin,

Haklısın galiba.

Where de şartlardan biri DropdownList1.SelectedItem.Value ve onunda DataSource u boş . Gerçi hatayı sorgu satırında vermediği için şüphelenmedim.

Ama DropDownList  yerine  bir değer girince  de çalıştı.

Bana ilginç geldi. Bu sorgu ilk haliyle ne döndürüyor acaba, çünkü herhangi bir hata döndürmediğine göre birşey döndürüyor olmalı. smile

4

Re: Yine Linq

Ilk haliyle derken:

C#
dim query = from q  in db.bankalar where a=b and c=d select q


satirini mi kastediyorsun? Oyleyse, o hicbir sey dondurmuyor. O sadece "query" adinda bir degisken tanimliyor. Tipi IQueryable<banka> gibi birsey. VFP'deki:

Visual Fox Pro
lcSQL = "select * from tabloadi where a = ?m.b and c = ?m.d"


gibi sadece sorguyu tanimlayan bir satir. VFP'de:

Visual Fox Pro
b = "xx"

d = "yy"
SQLExec(m.Handle, m.lcSQL, 'sonuc')

denince o SQL server'a gonderilip calistiriliyor. Linq'da da calistigi yer onun kullanildigi yer. Enumeration gerektiren herhangi bir komut.

C#
if query.Count() > 0 

 
for each (var o in query)
 
query.ToList()

vs.

5

Re: Yine Linq

Visual Fox Pro
Dim obnk = From b In db.bankalars Where b.sid = Val(Session("Field1")) And b.id = bnk.SelectedItem.Value Select b

            If obnk.Count > 0 Then  &&HATAYI BURDA VERİYORDU
                For Each bn In obnk
                    ban = bn.banka
                    hsp = bn.hesap
                Next
            End If

Kod yukarıdaki gibi, Sorgu sorunsuz gibi çalışıyor. ama sonucu For Each döngüsüne  soktuğumda "Tanımsız nesne falan ..." diye bir hata veriyor.

Ben acaba sonuç boşmu diye kontrol etmek için If obnk.count()... kontrolunu koyduğumda ondada aynı hatayı veriyor. Aslında problem dropdownlistte herhangi bir item olmamasından kaynaklanıyor ama bu olabilir.

Bu durumda, hatayla karşılaşmamak için önce bana gereken sorgunun hata oluşturup oluşturmayacaını kontrol etmem gerekiyor. Yada bilmediğim birşeyler var.

6 Son düzenleyen, cetinbasoz (27.10.2010 10:16:05)

Re: Yine Linq

Ya VB cok zor, yazana kadar canim cikiyor:)

C#
dim sidStr as string

dim sid as integer
if (Session("Field1")) is nothing then
  sidStr = ""
else
  sidStr = Session("Field1")
end if
if not Int32.TryParse(sidStr, sid) then sid = 0
 
if sid > 0 and not bnk.SelectedItem is nothing
  '...
end if

7

Re: Yine Linq

Evet tüm bu kontrolleri yapmam lazım da linq bunu niye yapmıyor yahu smile , boş bir tablo döndürse yeterdi. Neyse kullanım konforu açısından VFP ile karşılaştırmayı bıraksam iyi olacak smile

8

Re: Yine Linq

Haklisin, karsilastirinca Linq daha rahat ama VFP ile de calismam lazim. C# olsa asil o zaman cok rahat, VB bana hep roket muhendisligi gereken dil gibi geldi:)

9 Son düzenleyen, avrasya34 (03.11.2010 01:06:16)

Re: Yine Linq

cetinbasoz yazdı:

lcSQL = "select * from tabloadi where a = ?m.b and c = ?m.d".

hocam bu satırdaki a = ?m.b and c = ?m.d "  soru işaretleri ne işe yarıyor ?

10

Re: Yine Linq

? ile başlayan değerler parametre.
Yani o parametreleri daha önce bir yerlerde tanımladın ve atama yaptın diyelim. :

m.b= "İSTANBUL"
m.d= "KADIKÖY"

lcSQL = "select * from tabloadi where a = ?m.b and c = ?m.d"

ile

lcSQL = "select * from tabloadi where a = "İSTANBUL" and c = "KADIKÖY""

aynı.

Özellikle Cursor Adapter yada SPT kullanıyorken pratik kullanım sağlıyor.

Uğur
-------------------------------------------------------------------------------------------------------------
Hayat bir bisiklete binmek gibidir. Pedalı çevirmeye devam ettiğiniz sürece düşmezsiniz. Claude Peppeer
Kusuru söylenmeyen adam, ayıbını hüner sanır.  Türk Atasözü

11

Re: Yine Linq

Ugur cok guzel anlatmis, ufak bir ekleme (kafa karisikligina karsi). SQL sorgusunu daha o parameterler yokken yazabilir ve hatta baska bir fonksiyona gonderebilirsin (o sirada duz string, daha icindeki parametreler aranmiyor). Istedigin zaman parametreyi tanimlar, degerini verirsin ve sorguyu kullanabilirsin, Sonra parametre degerini degisitirip gene sorguyu kullanabilirsin. Ornegin (ornegin uzun gorundugune bakma ornek verirken birden fazla seye ornek olsun diye jenerik cursoradapter class var icinde. O class bir kere yazilip kenarda kullanima hazir duran sey. Asil kod bastaki birkac satir. SQL serverdan Customers datasi verilen ulkeye gore alinip edit ediliyor. Dikkat et tanim once, kullanim sonra 'USA' ve 'UK' ile iki kez):

Visual Fox Pro
Local loCursor, lcConStr

 
lcConStr = 'Provider=SQLNCLI;Trusted_connection=Yes;Server=.\SQLExpress'
loCursor = Createobject('CaGeneric',m.lcConStr)
 
With loCursor
  .Alias          = 'myTable'
  TEXT TO .SelectCmd  noshow
SELECT * FROM NorthWind..Customers cus WHERE country = ?m.Country
  ENDTEXT
Endwith
 
Country = 'USA'
If loCursor.QueryFill()
  Select (loCursor.Alias)
 
  loCursor.MakeUpdatable('NorthWind..Customers','customerId')
  Browse Last
  Tableupdate(2,.T.,loCursor.Alias)
Endif
 
 
Country = 'UK'
If loCursor.QueryFill()
  Select (loCursor.Alias)
 
  loCursor.MakeUpdatable('NorthWind..Customers','customerId')
  Browse Last
  Tableupdate(2,.T.,loCursor.Alias)
Endif
 
Define Class CaGeneric As CursorAdapter
  CompareMemo = .F.
  FetchAsNeeded = .T.
  FetchSize = 100
  FetchMemo = .T.
  BatchUpdateCount = 100
  WhereType = 1
  AllowSimultaneousFetch = .T.
  MapVarchar = .T.
  MapBinary = .T.
  BufferModeOverride = 5
 
  DataSourceType = 'ADO'
  InsertCmdDataSourceType = 'ADO'
  UpdateCmdDataSourceType = 'ADO'
  DeleteCmdDataSourceType = 'ADO'
 
  Procedure Init(tcConnectionString)
    Set Multilocks On
    Local loConnDataSource
    loConnDataSource = Createobject('ADODB.Connection')
    loConnDataSource.ConnectionString = m.tcConnectionString
    loConnDataSource.Open()
    This.Datasource = Createobject('ADODB.RecordSet')
    This.Datasource.CursorLocation   = 3  && adUseClient
    This.Datasource.LockType         = 3  && adLockOptimistic
    This.Datasource.ActiveConnection = m.loConnDataSource
    loCommand = Createobject('ADODB.Command')
    loCommand.ActiveConnection = loConnDataSource
    This.AddProperty('oCommand',loCommand)
    Store loCommand To ;
      This.UpdateCmdDataSource,;
      This.InsertCmdDataSource,;
      This.DeleteCmdDataSource
  Endproc
 
  Procedure MakeUpdatable(tcTableName,tckeyField,tlDoNotIncludeKey)
    This.Tables = m.tcTableName
    This.KeyFieldList = m.tckeyField
    Local ix, lnUpdateableFCount
    lnUpdateableFCount = Fcount(This.Alias)-Iif(This.DataSourceType='ADO',1,0) && last one is ADOBOOKMARK
    For ix = 1 To m.lnUpdateableFCount
      If !m.tlDoNotIncludeKey Or !(Upper(Field(m.ix,This.Alias,0)) == Upper(m.tckeyField))
        This.UpdatableFieldList = This.UpdatableFieldList + ;
          IIF(Empty(This.UpdatableFieldList),'',',') + ;
          FIELD(m.ix,This.Alias,0)
      Endif
      This.UpdateNameList = This.UpdateNameList + ;
        IIF(Empty(This.UpdateNameList),'',',') + ;
        TEXTMERGE('<<FIELD(m.ix,this.Alias,0)>> <<m.tcTableName>>.<<FIELD(m.ix,this.Alias,0)>>')
    Endfor
  Endproc
 
  Procedure QueryFill()
    Local llSuccess
    If This.DataSourceType ="ADO"
      llSuccess = This.CursorFill(.F.,.F.,0,This.oCommand)
    Else
      llSuccess = This.CursorFill(.F.)
    Endif
    If !m.llSuccess
      If This.DataSourceType ="ADO"
        lcMessage = This.oCommand.CommandText + Chr(13) + This.GetErrorExplanation()
      Else
        lcMessage = This.GetErrorExplanation()
      Endif
      Messagebox(m.lcMessage)
    Endif
    Return m.llSuccess
  Endproc
 
  Procedure GetErrorExplanation
    Local lcError,ix
    Local Array aWhy[1]
    Aerror(aWhy)
    lcError = ""
    For ix = 1 To 7
      lcError = m.lcError + Transform(aWhy[m.ix]) + Chr(13)
    Endfor
    Return m.lcError
  Endproc
Enddefine

Parametre faydali birsey olmaktan ote olmazsa olmaz birsey. Esneklik saglamasinin ve degiskenleri saglamasinin yaninda:

-Dogru yazmani saglar (ornegin SQL server'da [Ali'nin Sirketi] yazmak istiyorsan parametre ile oyle yazarsin, parametre kullanmazsan [Ali''nin Sirketi] yazman gerekir. Ya da tarih yazamak istediginde belli standard formatlardan biriyle string olarak yazmakla ugrasmazsin, dogrudan tarih yaz sen parametre olarak gitsin, nasil verilecekse driverlar cevirir):

Visual Fox Pro
lcSQL = "insert into myTable (kayitID, gelisZamani, aciklama, resim) values (?m.ID, ?m.TarihSaat, ?m.detaylar, ?m.resim)"

 
ID = 1
TarihSaat = datetime()
Detaylar = "Bir varmis bir yokmus, Ahmet'in vs vs ve hatta bir dosyadan tonlarca ek:" + FileToStr("c:\Temp\Detay.txt")
Resim = CreateBinary(FileToStr("c:\temp\BirResim.jpg"))
 
SQLExec(m.lnHandle, m.lcSQL)

-AMA EN ONEMLISI database'ine sizilmasini onler. Bu sizma 'SQL injection attack' olarak meshur ve en onemli ve veri tabani programcilarinin en ciddi 10 hatasi arasinda yer aliyor. Asla ve asla:

Visual Fox Pro
lcSQL = "select * from tabloadi where a = '" + m.a + "' and c = " + m.c

gibi bir SQL kullanma. Bunu yaparsan bir hacker sana minnettarligini yakinda sunacaktir. O sunmasa da boyle SQL yazdigini gorunce sana is vermezler, tek soruda cakarsin (hos gerci bu sekilde kullandigi halde su anda SQL DBA olani da taniyorum).

12

Re: Yine Linq

çok sağolun arkadaşlar bilgiler enfes