Temat: MVC, Autofac + EF

Witam,
proszę Was o wskazówkę jak powinnam podejść do poniższego zagadnienia.

Z tabeli:

CREATE TABLE [dbo].[Testowa](
[id] INT PRIMARY KEY NOT NULL,
[min] [int] NOT NULL,
[max] [int] NOT NULL,
[opis] [varchar](max) NOT NULL,
[data] [datetime])


muszę pobrać dane, które opisuje klasa:

public class Range<T>
{
int Id { set; get; }
T Min { set; get; }
T Max { set; get; }
}


Na poziomie kontrolera korzystam z generycznego repozytorium i LINQ:

private readonly IGenericUnitOfWork uow;
public AdministracjaController(IGenericUnitOfWork _uow)
{
this.uow = _uow;
}

public ActionResult Ranges()
{
List<Models.Testowa> tmp = uow.Repository<Models.Testowa>().GetOverview().ToList();
var ranges = (from ranges in tmp
select new Range<int?>
{
Id= ranges.id,
Min = ranges.min,
Max = ranges.max
}).ToList();
return View(ranges);
}


Konfiguracja Autofac jak poniżej:

builder.RegisterType<MyDBEntities>().SingleInstance();
builder.RegisterType<DB.GenericData.GenericUnitOfWork>().As<DB.GenericData.IGenericUnitOfWork>();


Na poziomie widoku dane prezentowane są w postaci tabeli, którą można modyfikować.
I teraz zastanawiam się czy nie powinnam użyć transakcji do zapisywania zmodyfikowanych "wierszy"? Tylko jeśli chcę użyć transakcji to muszę ich użyć także do pobierania danych. Inaczej wyglądałaby też konfiguracja Autofac.
Byłabym wdzięczna za wskazówki, ewentualne przykłady z transakcjami korzystającymi z kontenera Autofac.
Marek Kubiś

Marek Kubiś programista c#

Temat: MVC, Autofac + EF

Małgorzata B.:
.. I teraz zastanawiam się czy nie powinnam użyć transakcji do zapisywania zmodyfikowanych "wierszy"?
Hmm .. uważam, że nie. Przecież 'Autofac is designed for use in highly-concurrent applications.' więc dokładanie do tego 'na piechotę' transakcji kłóci się z ideą korzystania ze wzorca/narzędzia, które jest dedykowane do takich zastosowań. Rozumiem, że twoje obawy związane są z tym, że DBContext czy ObjectContext nie jest thread safe ale Autofac to inny poziom abstrakcji.
Tylko jeśli chcę użyć transakcji to muszę ich użyć także do pobierania danych. Inaczej wyglądałaby też konfiguracja Autofac.
Byłabym wdzięczna za wskazówki, ewentualne przykłady z transakcjami korzystającymi z kontenera Autofac.
O tym czy w twoim przypadku transakcje razem z Autofac będą ci potrzebne myślę, że nikt kto nie zna szczegółów nie jest odpowiedzieć, bo o tym decyduje logika biznesowa. To powinno wyjść z wymagań narzuconych przez analityka biznesowego.

To co może mieć znaczenie w twoim przypadku to przyjęta architektura całej aplikacji. Po prostu w środowisku wielodostępnym powinno się pamiętać aby instancje żyły tylko tyle ile jest to potrzebne i ani chwili dłużej. Ale ta uwaga odnosi się do naszego stylu programowania. Jeżeli będziemy o tym pamiętać to powinno być dobrze.

Może ktoś jeszcze dorzuci jakieś inne uwagi. Także może oryginalna dokumentacja coś podpowie, np. ta. Dodatkowo być może także interesująca wyda ci się ta dyskusja dotycząca tych samych problemów w środowisku UOW.

Temat: MVC, Autofac + EF

Dziękuję za odpowiedź.
Transakcje przyszły mi na myśl z tego względu, że przy zapisywaniu wielu wierszy może być sytuacja, że przy zapisie któregoś z nich może wystąpić błąd. A transakcją można wycofać dotychczasowe zmiany.
Rozumiem, że transakcja to zbiór pewnych operacji, które muszą zostać zrealizowane by osiągnąć zamierzony cel biznesowy.
Marcin S.

Marcin S. Programista, trener
i konsultant w
zakresie .NET/.NET
Cor...

Temat: MVC, Autofac + EF

Witaj,
Moje obawy budzi ten kawałek kodu:



public ActionResult Ranges()
{
List<Models.Testowa> tmp = uow.Repository<Models.Testowa>().GetOverview().ToList();
var ranges = (from ranges in tmp
select new Range<int?>
{
Id= ranges.id,
Min = ranges.min,
Max = ranges.max
}).ToList();
}


Ta linia

uow.Repository<Models.Testowa>().GetOverview().ToList();


zakłóca zasadę hermetyzacji.

Do czego służy ten fragment kodu?

from ranges in tmp
select new Range<int?>
{
Id= ranges.id,
Min = ranges.min,
Max = ranges.max
})


bo mam wrażenie, że zamienia tylko typ Testowa na Range. Takie mapowanie można załatwić po stronie Entity Framework za pomocą konfiguracji.

Zerknij najlepiej do projektu (przykład z mojego szkolenia):

https://github.com/sulmar/Altkom.WPFMVVM.201907/blob/ef...

Mój generyczny interfejs wygląda następująco:


public interface IEntityRepository<TEntity>
{
ICollection<TEntity> Get();
TEntity Get(int id);
void Add(TEntity entity);
void Update(TEntity entity);
void Remove(int id);
}


Następnie tworzymy interfejs dla konkretnego typu encji i w razie czego dodajemy szczególne metody:


public interface IVehicleRepository : IEntityRepository<Vehicle>
{
ICollection<Vehicle> Get(VehicleSearchCriteria criteria);
Task<ICollection<Vehicle>> GetAsync(VehicleSearchCriteria criteria);

}


Następnie tworzymy generyczną implementacją z użyciem Entity Framework:
https://github.com/sulmar/Altkom.WPFMVVM.201907/blob/ef...

i korzystamy z niej: https://github.com/sulmar/Altkom.WPFMVVM.201907/blob/ef...

Następnie rejestrujemy w kontenerze:



ContainerBuilder builder = new ContainerBuilder();

builder.RegisterType<DbVehicleRepository>().As<IVehicleRepository>();



i wstrzykujemy do kontrolera:


private readonly IVehicleRepository vehicleRepository;

public AdministracjaController(IVehicleRepository vehicleRepository)
{
this.vehicleRepository= vehicleRepository;
}

public ActionResult Index()
{
var vehicles = vehicleRepository.Get();
return View(vehicles );
}



W moim przykładzie nie korzystam ze wzorca UnitOfWork lecz tylko ze wzorca Repository. Ale sądzę, że do takiego przypadku wystarczy.

Mam nadzieję, że trochę pomogłem :)

Pozdrawiam,Ten post został edytowany przez Autora dnia 04.09.19 o godzinie 17:05

Następna dyskusja:

ASP.NET MVC eBook




Wyślij zaproszenie do