> For the complete documentation index, see [llms.txt](https://bekoturko.gitbook.io/yazilim-gelistirme-wiki/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bekoturko.gitbook.io/yazilim-gelistirme-wiki/uygulama-yapisi-ve-katmanlari/veri-erisim-katmani.md).

# Data - Veri Erişim Katmanı

### Açıklama

Bu belge veri erişim katmanı işlemlerini tanımlar. Veri erişim katmanı Veritabanı, Servis ve diğer veri kaynaklarına erişim için kullanılan katmandır.Bu katmanda:

* **İş mantığı bulunmaz**. (Sadece veri alma-verme işlemleri yapılır.)
* Veri istemcileri arayüzler üzerinden çalışır ve birim testleri oluşturulur.

### Veritabanı Erişimi

#### Repository metotları

Repository metotları temel olarak aşağıdaki adımlardan oluşur:

1. İstek bilgilerinin oluşturulması
2. Varsayılan dönüş değerinin tanımlanması
3. Veritabanı isteğinin yapılması ve sonucun döndürülmesi

**Örnek:**

```csharp
public bool UpdatePost(int postId, int memberId)
{
    var dataRequest = dataRequestFactory.UpdatePost(postId, memberId);
    var defaultReturnValue = false;

    return dataClient.GetScalar<bool>(dataRequest, defaultReturnValue);
}
```

#### DataRequest

Veritabanı işlemi istek bilgileri `IDataRequestFactory` aracılığıyla oluşturulur. Bu sınıfta istek bilgilerini içeren özel bir metot oluşturulur.

**Dikkat edilecek konular:**

1. Metot, çağrılacak prosedür ile aynı isme sahip olur.
2. Prosedür isimleri `ProcedureNames` sınıfında özellik olarak tanımlanır.
3. Parametre isimleri `ParameterNames` sınıfında özellik olarak tanımlanır.

**Vertabanı isteği oluşturma örneği:**

```csharp
public DataRequest UpdatePost(int postId, int memberId)
{
    string procedureName = ProcedureNames.UpdatePost;
    var parameters = new DynamicParameters();
    parameters.Add(ParameterNames.PostId, postId);
    parameters.Add(ParameterNames.MemberId, memberId);

    return new DapperDataRequest
    {
        ProcedureName = procedureName,
        Parameters = parameters
    };
}
```

**OUTPUT tipinde parametre kullanan bir örnek:**

```csharp
public int AddPost(Post post)
{
    var dataRequest = dataRequestFactory.AddPost(post);
    var defaultReturnValue = false;

    bool isSuccess = dataClient.GetScalar<bool>(dataRequest, defaultReturnValue);

    if (!isSuccess)
    {
        return 0;
    }

    return dataRequest.Parameters.Get<int>(ParameterNames.PostId);
}
```

Bu metot için veri isteği aşağıdaki gibi oluşturulur:

```csharp
public DataRequest AddPost(Post post)
{
    string procedureName = ProcedureNames.AddPost;
    var parameters = new DynamicParameters();
    parameters.Add(ParameterNames.PostSecureId, post.PostSecureId);
    parameters.Add(ParameterNames.MemberId, post.MemberId);
    parameters.Add(ParameterNames.PostTypeId, post.PostType.ToInt32());
    parameters.Add(ParameterNames.PostId, 0, DbType.Int32, ParameterDirection.Output, sizeof(int));

    return new DapperDataRequest
    {
        ProcedureName = procedureName,
        Parameters = parameters
    };
}
```

**SplitOn içeren veri isteği örneği:**

Sorgu sonucu dönen alanlar belli nesnelere göre gruplanarak alt sınıflar doldurulacaksa, ilgili nesnenin alanlarını döndüren alanlar belirtilir.

```csharp
public DataRequest GetProfileInfo(int memberId)
{
    string procedureName = ProcedureNames.GetProfileInfo;
    var parameters = new DynamicParameters();
    parameters.Add(ParameterNames.MemberId, memberId);

    return new DapperDataRequest
    {
        ProcedureName = procedureName,
        Parameters = parameters,
        SplitOnParameters = GetSplitOnParameters(ColumnNames.OccupationId, ColumnNames.EducationId)
    };
}

string GetSplitOnParameters(params string[] fieldNames)
{
    return string.Join(",", fieldNames);
}
```

Bu istek bilgilerini kullanan repository metodu aşağıda gösterilmiştir. `GetItem` metodu çağrılırken belirtilen ilk 3 tip (`ProfileInfo, Occupation, Education`) sorgunun ayrılacağı parçaları, son tip (`ProfileInfo`) dönüş tipini belirler.

```csharp
public ProfileInfo GetProfileInfo(int memberId)
{
    var dataRequest = dataRequestFactory.GetProfileInfo(memberId);
    ProfileInfo defaultValue = null;

    return dataClient.GetItem<ProfileInfo, Occupation, Education, ProfileInfo>(
        dataRequest,
        (profileInfo, occupation, education) =>
        {
            profileInfo.Education = education;
            profileInfo.Occupation = occupation;
            return profileInfo;
        },
        dataRequest.SplitOnParameters,
        defaultValue);
}
```

#### Varsayılan değerler

Veritabanı isteği başarısız olursa ya da döndürülecek bir kayıt bulunamazsa hangi sonucun döndürüleceği Repository metodunda yapılan çağrıda belirtilir.

`bool` tipinde dönüş değeri için varsayılan:

```csharp
var defaultReturnValue = false;
```

`int` ve sayısal dönüş değerleri için varsayılan:

```csharp
var defaultReturnValue = 0;
```

`string` tipinde dönüş değeri için varsayılan:

```csharp
string defaultReturnValue = null;
```

Sınıf tipinde dönüş değerleri için varsayılan:

```csharp
Post defaultReturnValue = null;
```

Özel durum için dönüş tipleri `IDefaultValueFactory` sınıfında tanımlanır.

```csharp
public PasswordActivation CreateDefaultPasswordActivation()
{
    return new PasswordActivation { IsActive = false };
}
```

Liste dönüş tipleri için varsayılan olarak boş liste döndürülür:

```csharp
var defaultValue = new List<Member>();
```

### Servis Erişimi

Servislere erişen Repository metotları temel olarak aşağıdaki adımlardan oluşur:

1. İstek bilgilerinin oluşturulması
2. İstek sonucunun uygun tipe çevrilmesi ve döndürülmesi
3. Hata kontrolü

Veritabanı istemcisi yerine Api istemcisi kullanılır. Diğer yönleriyle Veritabanı erişimi gibi tasarlanır ve kullanılır.
