Büyük sistemlere sahip Entity Framework - modelleri nasıl bölebilirsiniz?


50

1000+ tablo, birkaç yüz görüntü ve birkaç bin saklı yordam içeren bir SQL Server veritabanı ile çalışıyorum. Yeni projelerimiz için Entity Framework'ü kullanmaya başlamak istiyoruz ve bunu yapmak için stratejimiz üzerinde çalışıyoruz. Kapattığım şey, tabloları farklı modellere ayırmanın en iyi yoludur (önce kodu koyarsak EDMX veya DbContext). Hemen yarasadan birkaç strateji düşünebilirim:

  • Şemaya göre
    bölme Tablolarımız muhtemelen bir düzine şemaya bölünmüştür. Şema başına bir model yapabiliriz. Bu mükemmel değil, çünkü dbo hala 500'den fazla tablo / görüntüyle çok büyük oluyor. Başka bir sorun da, belli çalışma birimlerinin, EF'in bunu oldukça basitleştirdiğini kabul etmeme rağmen, karmaşıklığı artıran çoklu modelleri kapsayan işlemleri yapmak zorunda kalmalarıdır.
  • Niyete göre
    ayırma Şemalar için endişelenmek yerine, modelleri niyete göre ayırın. Bu nedenle, ne kadar granül almak istediğimize bağlı olarak her uygulama veya proje veya modül veya ekran için farklı modellerimiz olacak. Bununla ilgili gördüğüm sorun, kaçınılmaz olarak Kullanıcı ya da AuditHistory gibi her durumda kullanılması gereken bazı tablolar olması. Bunları her modele mi ekliyoruz (sanırım DRY'yi ihlal ediyor) veya bunlar her proje tarafından kullanılan ayrı bir modelde mi?
  • Hiç ayrılmayın - dev bir model
    Bu açıkça bir geliştirme perspektifinden basittir ancak benim araştırmam ve sezgilerime göre bu hem tasarım zamanında, hem de derleme zamanında ve muhtemelen çalışma zamanında korkunç performans göstermiş gibi görünüyor.

Böyle büyük bir veritabanına karşı EF kullanmanın en iyi yolu nedir? Özellikle insanlar bu DB nesneleri hacmine karşı model tasarımında hangi stratejileri kullanıyorlar? Bu işi, yukarıda sahip olduğumdan daha iyi düşünmediğim seçenekler var mı?

Ayrıca, bu NHibernate gibi diğer ORM'lerde bir sorun mu? Eğer öyleyse, EF'den daha iyi bir çözüm buldular mı?


"karmaşıklığı artıran birden fazla modeli kapsayan işlemleri yapmak zorunda" Buraya Microsoft Dağıtılmış İşlem Düzenleyicisi'ni etkinleştirmeniz gerekeceğine dair bir not. Bunu başlattıktan ve çalıştırdıktan sonra, bahsettiğiniz şeyi başarmak basit olmalıdır.
Tjaart

@Tjaart teşekkürler. MS DTC'yi daha önce kullanmıştım ve oldukça basitken, basit bir DB txn'nin ötesine karmaşıklık kazandırıyor, bu yüzden mümkün olduğunda önlemek istemiyorum.
RationalGeek

2
4 yıl sonra neye karar verdiniz ve şimdi ne önerirdiniz?
Rory

Yanıtlar:


31

Şahsen, tüm varlıklarım için oldukça karmaşık fakat küçük bir projede (~ 300 tablo) büyük bir şema yapmaya çalıştım. Çok sayıda "çoktan çoğa" ilişki ve aşırı referanssal bütünlük uygulama ile son derece normalleştirilmiş bir veritabanına (5. form normalizasyonuna (gevşekçe diyorum)) sahip olduk.

Ayrıca ikna olmadığım için “istek başına tek bir örnek” stratejisi kullandık.

Basit, makul ölçüde düz "açıkça tanımlanmış" listeleri yaparken, aramalar ve performans tasarrufu genel olarak kabul edilebilirdi. Ancak derin ilişkiler içine kazmaya başladığımızda, performans sert düşüyor gibi görünüyordu. Bu durumda depolanmış bir proc ile karşılaştırıldığında, hiçbir karşılaştırma (elbette) yoktu. Eminim ki burada ve burada performansın iyileştirilmesi için kod temelini değiştirmiş olabilirdik, ancak bu durumda zaman kısıtlamaları nedeniyle analiz etmeden sadece performans artışına ihtiyacımız vardı ve depolanan proc'a geri döndük (yine de haritalandırıldı) EF sayesinde, EF kesin olarak yazılan sonuçlar sağladığından), sadece birkaç alanda geri dönüş için buna ihtiyacımız vardı. Bir koleksiyon oluşturmak için tüm veritabanını taramak zorunda kaldığımızda (.include () kullanmadan), performans gözle görülür biçimde aşağılayıcıydı, ama belki çok fazla soruyorduk ..

Bu yüzden, tecrübelerime dayanarak niyet başına ayrı bir .edmx oluşturmanızı tavsiye ederim. Yalnızca bu ihtiyacın kapsamına göre kullanacağınız şeyi oluşturun. Amaçlanan görevler için daha küçük kapsamlı .edmx dosyalarınız olabilir ve ardından nesneler oluşturmak için karmaşık ilişkileri değiştirmeniz gereken bazı büyük dosyalar olabilir. Bu sihirli yerin nerede olduğundan emin değilim, ama eminim bir tane ... lol ...

Dürüst olmak gerekirse, gördüğümüz bazı tuzakların dışında (karmaşık travers), dev .edmx "çalışan" bakış açısıyla iyi çalıştı. Ancak, açıkça devre dışı bırakmazsanız, bağlamın sahnenin arkasında yaptığı "düzeltme" sihrine dikkat etmeniz gerekir. Veritabanında değişiklikler yapıldığında .edmx'i senkronize etmek dışında .. tüm yüzeyi silmek ve 3 dakika kadar süren varlıkları yeniden oluşturmak bazen daha kolaydı, bu yüzden büyük bir sorun değildi.

Bunların hepsi EntityFramework 4.1 ile oldu. Son seçiminizi ve deneyiminizi de duymak isterim.

Ve nHibernate hakkındaki sorunuzla ilgili olarak, bence solucanların sorduğu bir soru bu, çitin her iki tarafına da havlayacaksınız ... Bir sürü insanı, EF'in üzerinde çalışmaksızın su basması uğruna su basması için duyuyorum. EF'in kendine özgü nüanslarını zorlar ve anlar .. ve nHibernate'i üretimde hiç kullanmamış olmama rağmen, genel olarak, eğer elle ve açıkça haritalama gibi şeyler yapmak zorundaysanız, daha sınırlı bir kontrol elde edersiniz. n 'drop' u sürükleyebilir, üretebilir ve LINQ kullanarak CRUD'ing ve sorgulamaya başlayabilirim, granülerlik hakkında bir saçmalık verebilirim.

Umarım bu yardımcı olur.


1
FYI - Bu eşlemeleri ÇOK kolay ve otomatik hale getiren bir NHibernate Haritalama Programı var.
14'te

@ganders - Kullanıcı arayüzü var mı ve IDE entegrasyonu nasıl? Bunu bir veri kaynağına yönlendirdiğinizi ve referans bütünlüğüne ve nesne geçişine saygı duyduğunu ve eşleme nesnelerini yarattığını farz ediyorum.
hanzolo

1
Evet öyle (GUI). Şimdiye kadar sıfır sorun yaşadım. 4 veya 5 farklı projede / web sitesinde kullanıldı. Not: Eşleştirmeyi config / xml dosyalarında değil, c # kodunda yapan Fluent NHibernate ile kullanıyorum. İşte bir link: nmg.codeplex.com
ganders

13

Basit bir açıklama ile başlayalım: Bu kadar geniş veri tabanıyla ilgili deneyimim yok, bu yüzden cevabımın geri kalanı gerçek dünya örneğine dayanmıyor.

Böylece BÜYÜK bir veritabanınız var ve onu ORM / EF ile kullanmak istiyorsunuz. İkinci seçenekle giderdim. İşte basit açıklamamın nedeni:

  • Haritalama karmaşıklığı arttırır. Mevcut uygulamanızın / projenizin / modülünüzün asla ihtiyaç duymadığı varlıklara karmaşıklık eklemenize gerek yoktur, ancak ayrıntı düzeyi çok düşük yapmayın. Ekran başına ayrı harita setinin ayarlanması size de yardımcı olmaz.
  • Bir iş birimi elde etmek istiyorsun. Çoğu durumda hangi tablo modülünün ihtiyaç duyduğunu belirtebilmelisiniz (her durumda gerekli değildir). Bu tabloları tek haritalama setine yerleştirirseniz, okuma ve veri modifikasyonunu tek bir bağlam örneği ile idare edebileceksiniz - bu, nihai hedefiniz ne olmalıdır.
  • Modelle tam olarak ne demek istediğinizi tam olarak bilmiyorum ama farklı harita kümeleriyle bile, aynı varlık türlerini kullanarak harita kümeleri arasında sınıfları paylaşabilirsiniz. Öyleyse, User tablosunu iki modülde kullanırsanız, aynısını temsil etmek için iki User sınıfına ihtiyacınız yoktur. Tek bir tablo bile kullanabilirsiniz ve kod eşlemesi durumunda (aka code-first) bir kez bile haritalamayı tanımlayabilir ve birden fazla harita setine yükleyebilirsiniz; böylece DRY ilkesi ihlal edilmez, ancak kod ilk yaklaşımı söz konusu olduğunda daha fazla sınırlama vardır. görüşlere ve saklı prosedürlere. EDMX bunu zorlaştırıyor. Yine sınıfları yeniden kullanabilirsiniz, ancak haritalamayı tekrar kullanmak imkansızdır.
  • Çapraz modül sorguları ne durumda? Bu sorular olabilir ama dürüst olmak gerekirse her şey EF tarafından ele alınmamalıdır. Düzenli veri erişimini kolaylaştırmak için yaygın durumlar için EF'den yararlanabilirsiniz, ancak 5 farklı modüle ait tabloları birleştiren özel bir sorguya ihtiyacınız varsa, doğrudan doğrudan çalıştırabilir veya saklı yordamda sarabilirsiniz. Yerel veri erişiminin% 100'ünün değiştirilmesi zor, karmaşık ve tersine üretken olabilir.
  • Son nokta sadece pratiktir: VS takımının bu kadar büyük nesnelerle çalışmaya hazır olduğuna inanmıyorum - tasarımcıda değil, ithalat aracıyla bile. VS2008'de geleneksel veri erişimi ve SQL Database projesi ile çok büyük bir veritabanı üzerinde çalışıyordum - karmaşık bir projeyle kullanıcı deneyimi çok kötüydü. Kullanılan tabloların sayısını düşük tutmalısınız - tasarımcı için kapak 100-200 arasında bir yerde olmalı, ancak tek bir bağlamla işlenen 100 tablo bile (haritalama seti), bir sınıf için çok fazla sorumluluk gibi sesler (100 set özelliğine sahip olacağınızı varsayalım) bağlamda maruz - iyi bir tasarım gibi görünmüyor).

4

Bu tür sorulara teknik açıdan karar veremeyeceğinizi söyleyebilirim. Kullanım durumunuza göre (kullanıcı hikayeleri, vb.) Mimarinizi oluşturmanızı tavsiye ederim. İlk önce işletme nesnelerinizi bulun. Bir varlık nesnesi, varsayılan olarak bir işletme nesnesi değildir. Genelde, varlık nesnelerinin önünde bir iş nesnesine sahip olursunuz. Ardından, kullanıcı gereksinimlerine bağlı olarak gerçekte neye ihtiyacınız olduğuna karar verebilirsiniz.

"İyi bir mimar, verilmeyen kararların sayısını en üst düzeye çıkarır." Robert C. Martin

http://cleancoder.posterous.com/architecture-deference


3

Karma bir yaklaşım kullanıyorum - OLTP işleri EF tarafından, toplu ekler, toplu güncellemeler, rapor sorguları vb. Ağır işlemler Stored Procs tarafından gerçekleştirilir. Ayrıca, veri katmanınızı bir defada tam olarak yeniden yazmıyorsanız, geçiş yolunu kolaylaştırır.


Bu iyi bir strateji gibi gözüküyor, ancak farklı EF modellerinde varlıkların nasıl bölüneceği sorusunu gerçekten ele almıyor. Tek bir modelde bütün varlıklar var mı, yoksa bir şekilde bölüp ele geçiriyor musunuz?
RationalGeek

1
OLTP performansı tam model yaklaşımı için yeterliyse, bununla devam edin. Gerekirse daha sonra her zaman parçalayabilirsiniz, ancak en hızlı ve en çevik yol her şeyi yüklemektir. Ayrılmadan elde ettiğiniz performans kazanmalarına asla ihtiyacınız olmayabilir, bu nedenle zaman kaybetmeden ve sisteminizi sebepsiz yere daha karmaşık hale getirirsiniz. Ardından, genişletmeye karar verdiğinizde hangi modele yeni bir tablo / varlık ekleyeceğiniz sorusu var. Ve birden fazla modelde güncelleme yapmanız gerektiğinde ne olur. Gerçekten başka bir seçeneğin yoksa baş ağrısını kurtar.
Nik

Verilerinize erişirken performansınızı her zaman ayarlayabileceğinizi söylemeyi unuttum. Tembel / istekli yükleme seçeneklerine ve getirdiğiniz çocuk varlıklarına bakın. Masif nesne ağaçları yüklemiyorsanız, tam bir modelin neden daha küçük bir modelden daha kötü davrandığını düşünmüyorum.
Nik

büyük şema ağaçlarının ve normalleştirilmiş bir veri yapısının büyük
şemalarla

Nesne grafiğini ne kadar az veya ne kadar doygun hale getirmek istediğinizi kontrol edersiniz.
Nik
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.