/// <summary> /// Save new or modified item to data store /// </summary> /// <param name="address">the data address of the item, can be null if not available</param> /// <param name="data">the item to save</param> /// <param name="setOptions">list of options for saving, some may be custom</param> /// <returns>true if new record created</returns> public bool Set(Address address, object data, Dictionary <string, object> setOptions) { CodeTimer.MarkTime("Set START"); var wasSet = Registered(data.GetType()).Set(address, data, setOptions); CodeTimer.MarkTime("Set END"); return(wasSet); }
/// <summary> /// Get a data item by its item id /// </summary> /// <typeparam name="T">return type, this can be a summmary type, a content type, or a class from which several content types inherit</typeparam> /// <param name="id">the item id</param> /// <returns>content item</returns> public T Get <T>(ItemId id) where T : class { CodeTimer.MarkTime("Get via single id START"); var item = Registered(id.Type).Get <T>(new ItemId[] { id }).FirstOrDefault(); CodeTimer.MarkTime("Get via single id END"); return(item); }
/// <summary> /// Get a data item, or list of items, via the route which maps to them /// </summary> /// <typeparam name="T">type of the item(s), a generic list if a list of items, could be a summary type</typeparam> /// <param name="contentType">the content type of the item(s)</param> /// <param name="rd">route data</param> /// <returns>the mapped items(s)</returns> public T Get <T>(Type contentType, RouteData rd) where T : class { CodeTimer.MarkTime("Get via route START"); try { if (typeof(T).IsGenericType && typeof(T).GetGenericTypeDefinition() == typeof(List <>)) { Type elType = typeof(T).GetGenericArguments()[0]; ICollator coll; List <Type> contentTypes; bool isSummary = typeof(Summary).IsAssignableFrom(elType); if (isSummary) { contentTypes = ContentTypeHierarchy.GetSummaryContainers(elType); if (contentTypes.Select(ct => Registered(ct)).Distinct().Count() != 1) { throw new Exception("Content types containing summary type " + elType.FullName + " dont have 1 unique registered collator, requirement for a dataroute with list type"); } coll = Registered(contentTypes.First()); } else { coll = Registered(elType); contentTypes = new List <Type> { elType }; } T itemList = (T)ReflectionX.InvokeGenericMethod(coll, "GetList", new Type[] { elType, isSummary ? elType : ContainerType(elType) }, contentTypes, rd); return(itemList); } else { ICollator coll = Registered(contentType); return(coll.Get <T>(new List <Address> { coll.GetAddress(contentType, rd) }).FirstOrDefault()); } } finally { CodeTimer.MarkTime("Get via route END"); } }
/// <summary> /// Get data items via a list of ids /// </summary> /// <typeparam name="T">type to which returned items are cast, can be summary</typeparam> /// <param name="ids">ItemIds to find</param> /// <returns>enumerable of summary or content types</returns> public IEnumerable <T> Get <T>(IEnumerable <ItemId> ids) where T : class { CodeTimer.MarkTime("Get by ids START"); try { foreach (var idg in ids.Where(id => id != null).GroupBy(id => Registered(id.Type))) { foreach (var res in idg.Key.Get <T>(idg)) { yield return(res); } } } finally { CodeTimer.MarkTime("Get by ids END"); } }
/// <summary> /// Get data items via a list of data addresses /// </summary> /// <typeparam name="T">type of the items</typeparam> /// <param name="addresses">data addresses of the items</param> /// <returns>list of data items</returns> public IEnumerable <T> Get <T>(IEnumerable <Address> addresses) where T : class { CodeTimer.MarkTime("Get by addresses START"); try { foreach (var ag in addresses.Where(a => a != null).GroupBy(a => Registered(a.Type))) { foreach (var res in ag.Key.Get <T>(ag)) { yield return(res); } } } finally { CodeTimer.MarkTime("Get by addresses END"); } }
/// <summary> /// Get items via a query /// </summary> /// <typeparam name="T">return type, this can be a summmary type, a content type, or a class from which several content types inherit</typeparam> /// <typeparam name="TQuery">the type in terms of which the query is expressed: the content type or possibly a class from which several content types inherit</typeparam> /// <param name="types">a list of content types across which the query will be applied</param> /// <param name="queryBody">a function which takes an iqueryable and adds the query to the end of it</param> /// <returns>list of items of (or cast to) return type</returns> public IEnumerable <T> Get <T, TQuery>(IEnumerable <Type> types, Func <IQueryable <TQuery>, IQueryable <TQuery> > queryBody) where T : class where TQuery : class { CodeTimer.MarkTime("Get by query START"); try { var tgs = types.Where(t => t != null).GroupBy(t => Registered(t)).ToList(); foreach (var tg in tgs) { foreach (var res in tg.Key.Get <T, TQuery>(tg, queryBody)) { yield return((T)res); } } } finally { CodeTimer.MarkTime("Get by query END"); } }