Διάβαζα χτες μία δημοσίευση στο blog του Fredrik Normén για την τελευταία δημιουργία του, το ForkCan.com. Ωραία ιδέα, παρεπιπτόντως. Κοιτώντας μέσα στον κώδικα που είναι στο site, είδα {1}, {2} implementations για Generic Entity Framework 4.0 Base Repository.
Αν και μοιάζουν αρκετά, και ξεκινούν από παρόμοιο Interface, μου "ξίνισαν" μιας και το Repository pattern "θα έπρεπε" να είναι συνδυασμένο με το ένα "Unit of Work" pattern. Οπότε ξεκίνησα να γράφω στο Notepad...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
namespace RepositoryWebAppv2.Model
{
public interface IRepository<TEntity, TContext>
where TEntity : class
where TContext : class
{
IQueryable<TEntity> GetQuery();
IList<TEntity> FetchAll();
IList<TEntity> Fetch(Expression<Func<TEntity, bool>> where);
TEntity FetchSingle(Expression<Func<TEntity, bool>> where);
int Create(TEntity entity);
void Update(TEntity entity);
void Delete(TEntity entity);
}
} |
Μετά είπα να "πρωτοτυπήσω" και να κάνω ένα abstract class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
namespace RepositoryWebAppv2.Model
{
[DataObject]
public abstract class Repository<TEntity, TContext> : IRepository<TEntity, TEntity>
where TEntity : EntityObject, new()
where TContext : ObjectContext, new()
{
private TContext _ObjectContext;
public Repository()
{
_ObjectContext = new TContext();
}
public Repository(TContext objectContext)
{
if (objectContext == null)
throw new ArgumentNullException("objectContext");
_ObjectContext = objectContext;
}
#region ' IRepository<TEntity,TEntity> Members '
public IQueryable<TEntity> GetQuery()
{
return _ObjectContext.CreateObjectSet<TEntity>();
}
[DataObjectMethod(DataObjectMethodType.Select, true)]
public IList<TEntity> FetchAll()
{
return _ObjectContext.CreateObjectSet<TEntity>().ToList();
}
public IList<TEntity> Fetch(Expression<Func<TEntity, bool>> where)
{
return _ObjectContext.CreateObjectSet<TEntity>().Where(where).ToList();
}
public TEntity FetchSingle(Expression<Func<TEntity, bool>> where)
{
return _ObjectContext.CreateObjectSet<TEntity>().SingleOrDefault(where);
}
[DataObjectMethod(DataObjectMethodType.Insert, true)]
public int Create(TEntity entity)
{
return _ObjectContext.CreateObjectSet<TEntity>().AddObject(entity);
}
[DataObjectMethod(DataObjectMethodType.Update, true)]
public void Update(TEntity entity)
{
if (entity.EntityState == EntityState.Detached)
_ObjectContext.Attach(entity);
}
[DataObjectMethod(DataObjectMethodType.Delete, true)]
public void Delete(TEntity entity)
{
_ObjectContext.CreateObjectSet<TEntity>().DeleteObject(entity);
}
#endregion
}
}
} |
"Καμαρώνοντας" τη δημιουργία μου, είπα να τη τρέξω, αλλά η μόνη "πρόχειρη" έκδοση Visual Studio που είχα ήταν το Visual Studio 2008, μιας και βαριώμουν να σηκώσω ένα άλλο VM που είχε Visual Studio 2010. Κάνοντας copy & paste τον κώδικά μου, έφτιαξα και το πρώτο repository entity μου:
1
2
3
4
5
|
namespace RepositoryWebAppv2.Model
{
public class CustomerRepository : Repository<Customer, NorthwindEntities>
{ }
} |
Και αυτό που πήρα ήταν ένα σφάλμα - δεν χρειάστηκε πολύ να συνειδιτοποιήσω ότι ο κώδικας που είχα γράψει είχε target το EF4 και όχι το EF που έχει το .NET Framework v3.5 SP1. "Μικρό το κακό" σκέφτηκα, και έγραψα μερικές Extension Methods για να το "στρώσω" και για το EF1:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
public static partial class Extensions
{
public static ObjectQuery<T> CreateObjectSet<T>(this ObjectContext objectcontext)
where T : EntityObject
{
return objectcontext.GetType().GetProperties().OfType<ObjectQuery<T>>().FirstOrDefault();
}
public static void DeleteObject<T>(this ObjectQuery<T> entityset, T entity)
where T : EntityObject
{
entityset.Context.DeleteObject(entity);
}
public static int AddObject<T>(this ObjectQuery<T> entityset, T entity)
where T : EntityObject
{
try
{
entityset.Context.AddObject(entityset.Name, entityset);
}
catch (Exception)
{
return 0;
}
return 1;
}
} |
Και ενώ ήμουν "χαρούμενος" ότι θα έτρεχε, είδα ότι το extension method CreateObjectSet() δεν μου γύριζε ObjectSet<T> που ήθελα, αλλά επέστρεφε πάντα null.
Κάποια ιδέα γιατί το εν λόγω method δεν συμπεριφέρεται όπως περίμενα; "Φώτα" κάποιος;
George J.