invecklaren skrev:
Två i mitt tycke motstridiga funderingar?
Inte alls, helt logiskt tycker jag! :)
invecklaren skrev:
Hur hade ni löst detta ?
Precis som du förklarat!
20 svar · 1 683 visningar · startad av invecklaren
Hej!
Jag bygger en applikation som ska visa artiklar om orter/städer. En artikel kan kopplas till flera städer och det kan förstås finnas flera artiklar om en och samma stad.
Nu har jag skrivit klasserna Artikel och Stad, men frågan är hur dessa ska relateras.
Jag är förstås intresserad av att visa alla artiklar om en Stad. Ska då staden ha en property som är en collection av artiklar?
Samtidigt kan man vara intresserad av att visa en artikel och alla städer som är kopplade till artikeln. Detta indikerar att en Artikel borde ha en property som är en Collection av städer?
Två i mitt tycke motstridiga funderingar?
Hur hade ni löst detta ?
Databasmässigt är det inga problem, jag har en tabell för artiklar, en för städer och en för relationer.
invecklaren skrev:
Två i mitt tycke motstridiga funderingar?
Inte alls, helt logiskt tycker jag! :)
invecklaren skrev:
Hur hade ni löst detta ?
Precis som du förklarat!
Håller med dogge...
Även jag skulle gjort så :)
Nu hoppar jag in och är jobbig, jag tycker inte att en artikel skall ha en lista med orter.
En artikel är för mig en artikel och skall inte ha några kopplingar till orter på objektnivå, men i databasen bör den finnas. Om man vill ha den i objektnivån bör det snarare vara så att orten har en lista med artiklar men jag hade helst sett att en service hade skött det där.
IEnumerable<Article> ArticleService.GetByCity(city)
void ArticleService.RegisterArticleWithCity(Article article, City city);
Intressant med olika svar...
Nickemannen: Tänk dig att jag ska visa de fem senaste (senast inlagda) artiklarna i GUI:et. Jag har en sp som returnerar dessa och kod för att bygga upp instanser av Artikel och returnera en lista av artiklar till GUI:et. Jag får inte riktigt in det scenariot i det du beskriver. Hur skulle du löst det?
Intressant med olika svar...
Nickemannen: Tänk dig att jag ska visa de fem senaste (senast inlagda) artiklarna i GUI:et. Jag har en sp som returnerar dessa och kod för att bygga upp instanser av Artikel och returnera en lista av artiklar till GUI:et. Jag får inte riktigt in det scenariot i det du beskriver. Hur skulle du löst det?
Det hänger ju lite på hur du skiktat upp koden men typ så här:
IEnumerable<Article> articles = ArticleService.GetTop5ByCity("Sandviken");
Repeater1.DataSource = articles;
Repeater1.DataBind();
Och i GetTop5ByCity metoden så hämtar du din procedur och fyller listan.
Jag är nog inne på Nickemannens spår. För mig är det två klasser som inte har någon relation till varandra utanför er app. Fast det är inte helt galet att låta de finnas som properties heller. Det beror väl på applikationens omfång, är det inte alltid vettigt att Stad har en Artikel-property (och det omvända) skulle jag inte bygga en komposit klass utan göra som Nickemannen skriver.
Jag har faktiskt funderat över samma fråga även om domänmodellen skiljer sig lite. Om man har ett system för att, eh, hantera författare och böcker; skulle det vara rimligt att låta:
Egentligen handlar det väl om hur man vill ha sin kod strukturerad. Det finns purister som tänker för mycket och går för långt medan det finns andra som inte tänker tillräckligt långt.
Det här skulle jag vilja säga är en smaksak.
Jag håller med Nickemannen i detta han tog upp. Ett annat klassiskt exempel är Kund och Order. Ska tex ordern känna till kunden eller ska kunden känna till sina ordrar eller ska det vara både och. Man brukar rekommendera att undvika bidirektuella relationer så långt det bara går, dvs det sistnämnda, eftersom det har en tendens att göra domänen mer svårförvaltad.
Så Nickemannens förslag tycker jag låter bra.
En annan sak att tänka på om man väljer att ha bidirektuella relationer är hur man laddar sin data, för om man inte tänker till så får man en oändligt loop.
En Artikel som har en Stad i sig, denna stad har en artikel i sig, denna artikel har ju en stad i sig som ju har en artikel i sig, som ju har en stad i sig, som ju har en artikel i sig... osv osv *out of memory exception*
Man löser det ofast med LazyLoading genom att inte hämta artikeln eller staden från det att den behövs och då så hämtar man inte relationen till staden eller artiklen utan de hämtas först när de behövs...
LazyLoading har dock sina nackdelar och man bör fundera över om dessa överväger vinsten med att ha bidirektuella relationer.
Så jag håller med nickemannen, skapa en services som hämtar ut dina objekt som du vill ha. Dock är jag inte lika säker att man kan avslå relationerna bara för att man "i verkliga" livet inte har relationer mellan artiklar och städer, det styrs helt och hållet av hur domänmodellen ser ut och den behöver inte se ut som verkligheten även om det oftas blir enklare att förstå den om den gör det...
- M
Men Nickemannen mfl tycker jag förutsätter att man utgår från en stad och sedan hittar dess artiklar. Ibland är det ju så att jag vill ha fram de fem senaste artiklarna oavsett stad och att ta fram dessa artiklar genom en service t ex ArticleService.GetTop5ByCity() känns väl lite avigt? Eller?
Men Nickemannen mfl tycker jag förutsätter att man utgår från en stad och sedan hittar dess artiklar. Ibland är det ju så att jag vill ha fram de fem senaste artiklarna oavsett stad och att ta fram dessa artiklar genom en service t ex ArticleService.GetTop5ByCity() känns väl lite avigt? Eller?
Men Nickemannen mfl tycker jag förutsätter att man utgår från en stad och sedan hittar dess artiklar. Ibland är det ju så att jag vill ha fram de fem senaste artiklarna oavsett stad och att ta fram dessa artiklar genom en service t ex ArticleService.GetTop5ByCity() känns väl lite avigt? Eller?
Det finns inget som säger att du måste göra alla utsökningar med city.
IEnumerable<Article> ArticleService.GetTop(int top);
void Save(Article article)
void Map(Article article, City city)
IEnumerable<Article> GetByCity(City city)
IEnumerable<Article> GetAll()
Article Get(Guid id)
Sedan kanske det inte är en service/repository du skall ha för själva utsökningen, tycker själv om det som Ayende skriver om Query Object Pattern, men att börja diskutera det kanske inte passar in i denna diskussionen.
Sedan vet jag inte om jag blandar in mig för mycket i domänen, men det känns som att ort/stad kanske inte är det som borde användas utan butik för jag antar att meningen med stad/ort är att det finns butiker på olika orter, det skulle isådanafall lösa om det skulle vara så att det blir 2 butiker på samma ort. Då butiken egentligen har en City och i detta fallet kanske det är rätt att ha artiklar på butik, är man dock i adminverktyget och listar alla butiker kan det bli ganska trögladdat så därför tycker jag nog fortfarande att man skall särskilja artiklarna och butiken och låta en service ta hand om det. Om du använder dig av en O/R mapper och vill ha objekt så att du slipper sql osv så hade jag i servicemetoden haft ett mappningsobjekt säg att vi kör på butikscenariot
internal class PointOfSaleArticleMapping
{
internal PointOfSaleArticleMapping(PointOfSale pointOfSale, Article article)
{
// sätter vördena till propertiies som mappas i or/mappern
}
}
public class ....Service
{
......
public void Map(PointOfSale pointOfSale, Article article)
{
var mapping = new PointOfSaleArticleMapping(pointOfSale, article);
ormapper.save(mapping);
}
}
En artikel är i mitt fall en journalistisk produkt som handlar om en (eller flera) stad/ort. Jag använder ingen OR-mapper (är inte van vid det, även om jag fattar principen). SQL har jag inga som helst problem med att skriva.
Förstår jag det rätt som att relationen representeras av en egen klass och att denna klass sedan håller Artikeln och Staden som properties? Det låter ju onekligen vettigt.
En artikel är i mitt fall en journalistisk produkt som handlar om en (eller flera) stad/ort. Jag använder ingen OR-mapper (är inte van vid det, även om jag fattar principen). SQL har jag inga som helst problem med att skriva.
Förstår jag det rätt som att relationen representeras av en egen klass och att denna klass sedan håller Artikeln och Staden som properties? Det låter ju onekligen vettigt.
Japp och på det sättet får du din länkningstabell i detta fallet att bli representerat i domänmodellen även om den inte syns för utvecklarna utanför din service.
-> Nickemannen
Skulle du se denna länkningsklass som en DTO eller vad är det för klass? För en DTO känns som ett bra val för att hantera detta med fem senaste artiklarna.
-> Nickemannen
Skulle du se denna länkningsklass som en DTO eller vad är det för klass? För en DTO känns som ett bra val för att hantera detta med fem senaste artiklarna.
Ne jag ser den inte som en DTO klass, det är möjligt att man kan, jag har den enbart för att underlätta mappningen för en O/R Mapper, använder man inte en O/R Mapper kan man lika gärna skriva insert satsen direkt här i tabellen som länkar ihop artiklar och städer.
Sedan när jag skall göra utsökningen på alla artiklar för min speciella stad så hade det med nhibernate sett ut följande
var articles = From cityArticleMapping session.Linq<CityArticleMapping> Where cityArticleMapping.City = City Select cityArticleMapping.Article;
Ok, jag tror jag förstår hur du menar. Men bara för att checka av. Fyller Nhibernate cityArticleMapping med all data som finns. Sedan så använder du Linq för att filtrera ut de artiklar du vill?
Använder du sedan samma klass för att hämta ut alla artiklar för en stad via en annan linq-fråga bara?
lukaspojken skrev:
Fyller Nhibernate cityArticleMapping med all data som finns. Sedan så använder du Linq för att filtrera ut de artiklar du vill?
Inte som jag har förstått det, NHibernate skapar en SQL fråga utifrån ditt Linq-uttryck.
- M
lukaspojken skrev:
Fyller Nhibernate cityArticleMapping med all data som finns. Sedan så använder du Linq för att filtrera ut de artiklar du vill?
Inte som jag har förstått det, NHibernate skapar en SQL fråga utifrån ditt Linq-uttryck.
- M
Korrekt :)