Bir ASP.NET MVC uygulaması doğrudan model olarak Entity Framework'ü kullanmalı mı?


22

İlk MVC uygulamamı Visual Studio 2013'te (MVC 5) yapıyorum ve modelimi kurmanın en iyi yolunda biraz belirsizim.

Var olan bir veritabanındaki ilk kodu kullanarak bir varlık çerçeve modeli oluşturdum. İlk içgüdüm, görüşlerin kullandığı model olacak bazı aracı sınıfları oluşturmak ve bu sınıfların varlık çerçevesi sınıflarıyla çalışmasını sağlamaktı.

Aracı sınıfları yazarken, çoğunlukla EF sınıflarının ara sıra özel ayarlayıcıyla yaptığı ya da bir veri tipinden diğerine attığı birçok şeyi yeniden uyguladığımı fark ettim. Böylece bu bir atık gibi görünüyordu.

Varlık çerçevesi sınıflarını doğrudan bir MVC uygulaması için Model olarak kullanmak için genel kural mı? Yoksa bu ara sınıfları oluştururken kaçırdığım bir fayda var mı?



İlk önce kodu kullanıyorsanız, mevcut bir veritabanı yoktu, değil mi?
Isaac Kleinman

1
EF 6.1+ ile mevcut bir veritabanından ilk kod modelini oluşturabilirsiniz. Bu MSDN makalesine bakın: msdn.microsoft.com/en-au/data/jj200620.aspx
Mike D.

Yanıtlar:


23

Uygulamalarımda, her zaman veriyi (Entity Framework) ve MVC için farklı modellerle ayırdım. Bunları da farklı projelere ayırdım:

  • Örnek.Entities - EF için varlıklarımı ve bunlara erişmek için DB bağlamını içerir.
  • Örnek.Models - MVC modellerini içerir.
  • Example.Web - web uygulaması. Hem Example.Domain hem de Example.Models'e bağlı.

Etki alanı varlıkları gibi diğer nesnelere referans tutmak yerine, MVC modelleri kimlikleri tamsayılar olarak tutar.

Bir sayfa için bir GET isteği geldiğinde, MVC denetleyicisi bir varlık döndüren veritabanı sorgusunu gerçekleştirir. Bir etki alanı varlığı alıp onu bir MVC modeline dönüştüren "Dönüştürücü" yöntemleri yazdım. Bunun tersini yapan başka yöntemler de var (MVC modelinden etki alanı varlığına). Model daha sonra görüşe ve dolayısıyla müşteriye geçer.

Bir POST isteği geldiğinde, MVC kontrol cihazı bir MVC modeli alır. Bir dönüştürücü yöntemi bunu bir etki alanı varlığına dönüştürür. Bu yöntem aynı zamanda nitelik olarak ifade edilemeyen tüm doğrulama işlemlerini gerçekleştirir ve etki alanı varlığı zaten mevcutsa yenisini almak yerine güncellediğimizi doğrular. Yöntemler genellikle şuna benzer:

public class PersonConverter
{
    public MyDatabaseContext _db;

    public PersonEntity Convert(PersonModel source)
    {
         PersonEntity destination = _db.People.Find(source.ID);

         if(destination == null)
             destination = new PersonEntity();

         destination.Name = source.Name;
         destination.Organisation = _db.Organisations.Find(source.OrganisationID);
         //etc

         return destination;
    }

    public PersonModel Convert(PersonEntity source)
    {
         PersonModel destination = new PersonModel()
         {
             Name = source.Name,
             OrganisationID = source.Organisation.ID,
             //etc
         };

         return destination;
    }
}

Bu yöntemleri kullanarak, her denetleyicide başka türlü oluşabilecek kopyaları çıkarırım. Jeneriklerin kullanımı işleri daha da fazla tekilleştirebilir.

İşleri bu şekilde yapmak birçok fayda sağlar:

  • Bir modeli belirli bir görünüme veya eyleme göre özelleştirebilirsiniz. Gönderildiğinde, birçok farklı varlık (kişi, kuruluş, adres) oluşturan bir kişi için kayıt formunuz olduğunu varsayalım. Ayrı MVC modelleri olmadan bu çok zor olacaktır .
  • Görünüme aksi halde mevcut olandan daha fazla bilgi aktarmam gerekiyorsa veya iki varlığı tek bir modele dahil edersem, o zaman değerli veritabanı modelleri hiçbir zaman dokunulmaz.
  • Bir MVC modelini JSON veya XML olarak serileştirirseniz, bu duruma bağlı diğer tüm varlıkların değil, yalnızca hemen seri hale getirilmiş modeliniz olur.

İyi bir cevap, özellikleri bir sınıftan diğerine elle eşlemek yerine ValueInjector veya benzeri bir şeyi (kişisel olarak nefret ediyorum otomatikleştiriciden) kullanmanızı öneririm.
Rocklan

1
Ayrı bir cevap eklemek yerine, sadece DDD uygulamalarında "dönüştürücülerinizin" ve görünüm için ayrı modellerin Uygulama Hizmeti Katmanının bir parçası olarak değerlendirileceğini yorumlayacağım. Temel olarak, Etki Alanı Modelinizin uygulamadan bu karmaşıklığı gizlerken gerektiği kadar karmaşık olmasına izin verir. Aynı zamanda, etki alanı modelindeki bir değişiklik nedeniyle uygulamanın değiştirilmesi gerektiğinden de korur. ASL çeviriyi gerçekleştirir.
Michael Brown

Yani, bu modelin bilgisini almak için PersonModel'inizdeki (yani Organizasyon nesnesi) sahip olduğunuz her model için bir çağrı yapıyorsunuz? Kişiyi ve kuruluş bilgilerini güncellemek için bir formunuz olduğunu, Örgütü güncellediğinizde ek bir arama yapar mıydınız? Depolanan procs kullanıyorum bu yüzden modelin tüm özelliklerini ve içerdiği herhangi bir modelin özelliklerini aynı anda gönderemedim mi?
Işıltılı

1
Bir koleksiyonun eşlenmesini nasıl ele alırsınız? Artık EF6'da çok daha karmaşık gözüküyor, çünkü güncellemelerle yeni bir varlık listesi oluşturamazsınız, çünkü bu her şeyi yeniden yaratıyor ...
Gerard Wilkinson

2
Kendi dönüştürücü sınıflarınızı yazmak yerine, bu sorunu gidermek için yazılmış olan Automapper kütüphanesini kullanmanızı tavsiye ederim . 2014'ten bu yana çok olgunlaştı!
BenSmith

6

Bunun gerçekten uygulamanıza bağlı olduğunu söyleyebilirim. İş mantığı olmadan sadece saf CRUD mu yapıyor? Sonra EF modellerini doğrudan benim görüşüme göre kullanırdım.

Çoğu zaman en azından bazı iş mantıkları var ve ardından veri / EF modelleri ile görünüm arasında bir katman olması iyi bir fikir olabilir. Bu durumda, "CQRS-lite" (aşağıya bakınız) yapmanız ve kontrol cihazınızın içine ve dışına farklı modeller kullanmanız uygun olabilir. Okuma modelleri çoğu zaman yazma modellerinden çok daha "şişman" olur ...

Bununla birlikte, uygulama çok fazla iş mantığı içeriyorsa ve / veya çok fazla ölçeklendirmesi gerekiyorsa, en azından CQRS (Komut Sorgusu Sorumluluk Ayrımı), DDD (Etki Alanına Dayalı Tasarım) ve muhtemelen Olay Kaynaklama'yı kullanarak uygulamanın çekirdeğini uygulayacağım. Daha sonra EF, okuma modeli cephesi olarak kullanılabilir.

Ayrıca, tüm uygulama için bir stratejiye / kalıba uymanız gerekmediğini unutmayın, bazı alanlar saf CRUD olabilir ve diğer alanlar çok fazla iş mantığı içerebilir ...

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.