GÜNCELLEME: Son zamanlarda bu konuda birkaç oy aldım, bu yüzden insanların aşağıda verdiğim tavsiyenin en iyi olmadığını bilmelerini sağladım. Başlangıçta eski anahtarsız veritabanlarında Entity Framework ile uğraşmaya başladığım için, BY FAR ile yapabileceğiniz en iyi şeyin ters kod ilk önce yapmak olduğunu fark ettim. Bunun nasıl yapılacağı hakkında birkaç iyi makale var. Onları takip edin ve sonra bir anahtar eklemek istediğinizde, anahtarı "taklit etmek" için veri ek açıklamalarını kullanın.
Örneğin, Orders
birincil anahtar olmasa da, masamın bildiğini varsayalım , her müşteri için yalnızca bir sipariş numarasının olduğundan emin olabilirsiniz. Bunlar tablodaki ilk iki sütun olduğundan, kod ilk sınıflarını şöyle görünecek şekilde ayarladım:
[Key, Column(Order = 0)]
public Int32? OrderNumber { get; set; }
[Key, Column(Order = 1)]
public String Customer { get; set; }
Bunu yaparak, temelde EF'i OrderNumber ve Customer'dan oluşan kümelenmiş bir anahtar olduğuna inanarak taklit edersiniz. Bu, anahtarsız tablonuzda ekler, güncellemeler vb. Yapmanızı sağlar.
İlk önce Ters Kod yapmayı bilmiyorsanız, önce Entity Framework Kodu hakkında iyi bir öğretici bulun. Sonra ilk önce Ters Kod üzerinde bir tane bul (var olan bir veritabanıyla Kod İlk yapıyor). Sonra buraya geri dönün ve anahtar tavsiyeme tekrar bakın. :)
Orijinal Yanıt :
Birincisi: diğerlerinin söylediği gibi, en iyi seçenek tabloya birincil anahtar eklemektir. Tam durak. Bunu yapabiliyorsanız, daha fazla okuyun.
Ancak yapamıyorsanız veya sadece kendinizden nefret ediyorsanız, birincil anahtar olmadan bunu yapmanın bir yolu vardır.
Benim durumumda, eski bir sistemle çalışıyordum (aslen Access'e taşınan ve daha sonra T-SQL'e taşınan bir AS400'deki düz dosyalar). Bu yüzden bir yol bulmalıydım. Bu benim çözümüm. Aşağıdakiler benim için Entity Framework 6.0 (NuGet'in en sonuncusu).
Solution Explorer'da .edmx dosyanızı sağ tıklatın. "Birlikte Aç ..." ı ve ardından "XML (Metin) Düzenleyicisi" ni seçin. Burada otomatik olarak oluşturulan kodu el ile düzenleyeceğiz.
Bunun gibi bir çizgi arayın:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
Sondan çıkarın store:Name="table_name"
.
Değişim store:Schema="whatever"
içinSchema="whatever"
Bu satırın altına bakın ve <DefiningQuery>
etiketi bulun . İçinde büyük bir ol 'select deyimi olacaktır. Etiketi ve içeriğini kaldırın.
Şimdi hattınız şöyle görünmelidir:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
Değiştirecek başka bir şeyimiz var. Dosyanızı gözden geçirin ve şunu bulun:
<EntityType Name="table_name">
Yakınlarda, birincil anahtarın tanımlanmadığına dair sizi uyaran bazı yorumlanmış metinler göreceksiniz, bu nedenle anahtar çıkartıldı ve tanım salt okunur bir tablo / görünümdür. Bırakabilir veya silebilirsiniz. Ben onu sildim.
Aşağıda <Key>
etiketi. Entity Framework'ün ekleme / güncelleme / silme işlemleri için kullanacağı şey budur. BU DOĞRU OLDUĞUNDAN EMİN OLUN. Bu etiketteki özellik (veya özellikler), benzersiz bir şekilde tanımlanabilir bir satırı göstermelidir. Örneğin, orders
birincil anahtar olmasa da, masamın her müşteri için yalnızca bir sipariş numarasına sahip olduğundan emin olduğumu varsayalım.
Yani benimki şöyle görünüyor:
<EntityType Name="table_name">
<Key>
<PropertyRef Name="order_numbers" />
<PropertyRef Name="customer_name" />
</Key>
Cidden, bunu yanlış yapma. Diyelim ki asla kopya olmamasına rağmen, bir şekilde iki sıra aynı sipariş numarası ve müşteri adı ile sistemime giriyor. Whooops! Anahtar kullanmamaya çalıştığım şey bu! Bu yüzden birini silmek için Entity Framework kullanıyorum. Yinelenen bugün koymak tek sipariş olduğunu biliyorum, bunu yapmak:
var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);
Bil bakalım ne oldu? Ben sadece hem yinelenen VE orijinal sildi! Çünkü Entity Framework'e order_number / cutomer_name komutunun birincil anahtarım olduğunu söyledim. Yani duplicateOrder kaldırmak için söyledim, arka planda yaptığı gibi bir şeydi:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
Ve bu uyarıyla ... şimdi gitmek için iyi olmalısın!