So i am trying to retrieve an instance of the class "Sugar" for a specific date using this method in my UserDatabse.cs class:
public List<Sugar> GetSugarDate(DateTime dt)
{
var bld = database.Table<Sugar>().Where(mi => mi.Time.Date == dt.Date).ToList();
return bld;
}
*Keep in mind that the app doesn't have any instance of Sugar at the moment so the Date comparison is between a null and an actual date. I think that is causing the error, any solution would be appreciated.
The call to this method is made like this in another class:
DateTime Time = DateTime.Now;
ObservableCollection<Image> Sugar_Count = new ObservableCollection<Image>();
Image s = new Image();
s.Source = "drawable/soda.png";
var xa = App.Database.GetSugarDate(Time);
The class Sugar.cs is defined as follows:
public class Sugar
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public DateTime Time { get; set; }
public int DrinkCount { get; set; }
public Sugar()
{
Time = DateTime.Now;
DrinkCount = 0;
}
}
Now the error is get is as follows:
System.NotSupportedException: Member access failed to compile expression at SQLite.TableQuery'1[T].CompileExpr(System.Linq.Expressions.Expression expr, System.Collections.Generic.List'1[T]queryArgs)[0x006cc]in <9b4aaa861238418bec74a2ddde70f09>:0 at SQLite.TableQuery'1[T].CompileExpr(System.Linq.Expressions.Expression expr, System.Collections.Generic.List'1[T]queryArgs)[0x0009d]in <9b4aaa861238418bec74a2ddde70f09>:0 at SQLite.TableQuery'1[T].CompileExpr(System.Linq.Expressions.Expression expr, System.Collections.Generic.List'1[T]queryArgs)[0x0005f]in <9b4aaa861238418bec74a2ddde70f09>:0 at SQLite.TableQuery'1[T].CompileExpr(System.Linq.Expressions.Expression expr, System.Collections.Generic.List'1[T]queryArgs)[0x00008]in <9b4aaa861238418bec74a2ddde70f09>:0 at
System.Collections.Generic.List'1[T]..ctor(System.Collections.Generic.IEnumerable'1[T]collection)[0x00062] in /Users/builder/jenkins/workspace/xamarin-android/external/mono/mcs/class/referencesource/generic/list.cs:98 .....
The error occurs at this specific line:
var bld = database.Table<Sugar>().Where(mi => mi.Time.Date == dt.Date).ToList();
Where am i going wrong?
This part of the expression can not be translated to SQL.
mi => mi.Time.Date
You can try using:
var bld = database.Table<Sugar>().ToList().Where(mi => mi.Time.Date == dt.Date).ToList();
Accessing to the Date part of a DateTime column (mi.Time.Date) can not be translated to SQL using Linq, for this reason, your statement failed initially. So, using ToList fetches all records in memory allowing us to query with Linq to Object method not Linq to SQLite.
Its a little janky, but I have got this to work:
public List<Sugar> GetSugarDate(DateTime dt)
{
var dayStart = dt.Date.AddDays(-1);
var dayEnd = dt.Date.AddDays(1);
var bld = database.Table<Sugar>().Where(mi => mi.Time > dayStart && mi.Time < dayEnd).ToList();
return bld;
}
Also make sure you initialize your database connection with:
SQLiteConnection database = new SQLiteConnection(_path,false);
If you are querying a nullable DateTime
The little janky code worked for me
var dayStart = stockDate.Date.AddDays(-1);
var dayEnd = stockDate.Date.AddDays(1);
return db.Table<ProductStock>().Where(x => x.StockDate > dayStart && x.StockDate < dayEnd).ToListAsync();
Related
I've declared an API call in an interface and was wondering if it is possible to put constraints on some of the parameters. The API I'm accessing has these constraints as well and would like to enforce them in my program.
#GET("/recipes/search")
Call<RecipeResponse> getRecipes(
#Query("cuisine") String cuisine,
#Query("diet") String diet,
#Query("excludeIngredients") String excludeIngredients,
#Query("intolerances") String intolerances,
#Query("number") Integer number,
#Query("offset") Integer offset,
#Query("query") String query,
#Query("type") String type
);
How can I do this?
I know that it is possible to do this with POST request, and passing along an object via the RequestBody through the #Body annotation. Can I do this with a GET request too, where information is passed via the query string?
Thanks!
I think I ended up finding a solution. I've made a class SearchRecipeRequest in which I declare all possible parameters as class variables. In the setters I do the data validation such as checking for null on parameters that are required, or min/max value constraints on integers as specified by the endpoint. I then made a SearchRecipeRequestBuilder class to build such an object like so to make it easier to deal with all those possible parameters:
public class SearchRecipeRequestBuilder {
private String _cuisine = null,
_diet = null,
_excludeIngredients = null,
_intolerances = null,
_query = null,
_type = null;
private Integer _number = null,
_offset = null;
public SearchRecipeRequestBuilder() {}
public SearchRecipeRequest buildRequest() {
return new SearchRecipeRequest(_cuisine, _diet, _excludeIngredients, _intolerances, _number, _offset, _query, _type);
}
public SearchRecipeRequestBuilder cuisine(String cuisine) {
_cuisine = cuisine;
return this;
}
public SearchRecipeRequestBuilder diet(String diet) {
_diet = diet;
return this;
}
public SearchRecipeRequestBuilder excludeIngredients(String excludeIngredients) {
_excludeIngredients = excludeIngredients;
return this;
}
public SearchRecipeRequestBuilder intolerances(String intolerances) {
_intolerances = intolerances;
return this;
}
public SearchRecipeRequestBuilder query(String query) {
_query = query;
return this;
}
public SearchRecipeRequestBuilder type(String type) {
_type = type;
return this;
}
public SearchRecipeRequestBuilder number(Integer number) {
_number = number;
return this;
}
public SearchRecipeRequestBuilder offset(Integer offset) {
_offset = offset;
return this;
}
}
Which allows me to build the request like so:
SearchRecipeRequest request = new SearchRecipeRequestBuilder()
.query("burger")
.buildRequest();
I then pass along that object to a different function that knows how to use the request object to pass it along to the API.
That's how I'm doing it right now, if someone has a better way I'd love to hear it. :)
I got the idea to use the Builder pattern from a different StackOverflow question: Managing constructors with many parameters in Java.
When I try to index a doc of my defined type, having a list which is supposed to be mapped as a nested-object ("type":"nested"), it's getting mapped as a regular object type.
Take a look at the code:
I've got a simple class like this one:
[ElasticType()]
public class MyJob
{
[ValueFieldAttribute]
public int jobCode { get; set; }
[ValueFieldAttribute(Type = FieldType.nested)]
public IList<JobProfessionalFieldInfo> JobProfessionalFields { get; set; }
}
The code for the JobProfessionalFieldInfo class is:
[ElasticType()]
public class JobProfessionalFieldInfo
{
[ValueFieldAttribute]
public int JobId { get; set; }
[ValueFieldAttribute]
public int CategoryId { get; set; }
}
The code for the ValueFieldAttribute class is:
public class ValueFieldAttribute : ElasticPropertyAttribute
{
public ValueFieldAttribute()
: base()
{
this.Store = false;
this.Index = FieldIndexOption.not_analyzed;
}
}
My program:
static void Main(string[] args)
{
ConnectionSettings node = new ConnectionSettings(new Uri("http://localhost:9200"));
node.SetDefaultIndex("jobs");
ElasticClient client = new ElasticClient(node);
List<JobProfessionalFieldInfo> list = new List<JobProfessionalFieldInfo>();
list.Add(new JobProfessionalFieldInfo { CategoryId = 1, JobId = 1 });
list.Add(new JobProfessionalFieldInfo { CategoryId = 2, JobId = 2 });
var res = client.Index<MyJob>(new MyJob
{
jobCode = 1,
JobProfessionalFields = list
},"jobs", "MyJob",1);
}
Now, when I run it, it indexes the object successfully... BUT(!!) when I get the mapping of the index with GET jobs/MyJob/_mapping, I see that jobProfessionalFields has no "type":"nested" in its mapping.
That results in a query like the following one, returning the indexed doc while it's not supposed to get it back (that's what nested-type is for right?..):
GET jobs/_search
{
"query":
{
"bool":
{
"must":
[
{"match": {"jobId":1}},
{"match": {"categoryId":2}}
]
}
}
}
It's not the end:
I'd a look at here,
there the guy that answered tells that when we use annotations we need to manually call the createIndex and Map methods, but the problem is that I don't have any generic Map method...!
Take a look at here: (just to make you get into the link - here's its start..)
namespace Nest
{
public partial class ElasticClient...
And I don't know how to use the non-generic Map method to put the mapping of my MyJob class.
How can I cause this stuff to map the jobProfessionalFields as nested-type dudes?
Thanks for any help of you guys!
OK, got it LOL!
The MapFromAttributes<> is the right generic method for putting the mapping (at least in the current Nest version I'm using - 0.12.0).
But it demands a manual call for the index creationg, o.w it gives an IndexMissing exception (like the guy in the above mentioned link said).
client.CreateIndex("jobs", new IndexSettings { });
var res = client.MapFromAttributes<MyJob>("jobs","MyJob");
But that's really interesting why isn't it enough to just define the
[ElasticProperty(Type = FieldType.nested)],
in order to get the nested mapping though..
I would be glad to get an answer for that one.
// Hi everyone
i do this call in Action :
[HttpGet]
public virtual ActionResult JsonGetProvinces(int countryId)
{
//WebSiteContext WbContext = new WebSiteContext();
//UnitOfWork UnitofWork = new UnitOfWork(WbContext);
var provinces =
(
from province in unitofWork.ProvinceRepository.All
where province.CountryId == countryId
select new
{
Id = province.Id,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
}
).ToList();
return Json(provinces, JsonRequestBehavior.AllowGet);
}
something is wrong with my query :
var provinces =
(
from province in unitofWork.ProvinceRepository.All
where province.CountryId == countryId
select new
{
Id = province.Id,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
}
).ToList();
Particulary,
Name = province.GetType().GetProperty("Name_" + CultureManager.GetCurrentCultureShortName()).GetValue(province)
In BDD, there is Name_fr, Name_en columns
and i'm trying to take one dynamically... Is it possible ?
Of course, i can take both and choose dynamically the column in View but i would to know how do...
Thank you for your help
The short answer is you need to change your code a bit and using expression tree inside. Look at this question
EF can not translate function calls to SQL. Using expression trees can be comlicated see this question
Here is a sample with expression trees. The GetQuery2 is the same as GetQuery but with expression tree and a propertyname parameter.
public static IQueryable<Foo> GetQuery(BlogContext context)
{
var query = from x in context.BlogEntries
select new Foo
{
NameX = x.Name
};
return query;
}
public static IQueryable<Foo> GetQuery2(BlogContext context, string propertyName)
{
ConstructorInfo ci = typeof(Foo).GetConstructor(new Type[0]);
MethodInfo miFooGetName = typeof(Foo).GetMethod("set_NameX");
MethodInfo miBlogEntry = typeof(BlogEntry).GetMethod("get_" + propertyName);
ParameterExpression param = Expression.Parameter(typeof(BlogEntry), "x");
IQueryable<Foo> result = Queryable.Select<BlogEntry, Foo>(
context.BlogEntries,
Expression.Lambda<Func<BlogEntry, Foo>>(
Expression.MemberInit(
Expression.New(ci, new Expression[0]),
new MemberBinding[]{
Expression.Bind(miFooGetName,
Expression.Property(param,
miBlogEntry))}
),
param
)
);
return result;
}
It is easier the fetch all all language strings and write an additional Property Name that does the magic.
I am using JSON.Net to serialize my objects. For eg, if this is my object
Class MainData
{
[JsonProperty("keyValues")]
string val;
}
the data for 'val' is a key value pair string like this key1:value1.
I have a scenario where I should not get the above 'keyValues' name in my final serialized string and instead get a serialized string which looks like this
{
"key1":"value1"
}
Currently with my serializer I am getting this, which is not what I need
{
"keyValues":"key:value1"
}
Can somebody guide me to any documentation/solution to dynamically assign the name of the field instead of using the default variable name/JSONProperty Name defined inside the object?
Thanks a lot in advance.
I've been struggling with this all day, what I've done is used a dictionary object and serialised this
however I had an error message that was "cannot serialise dictionary", should have read the whole message, "cannot serialise dictionary when the key is not a string or object"
this now works for me and gives me a key/value pair
i have the following objects
public class Meal {
public int mealId;
public int value;
public Meal(int MealId, int Value) {
mealId = MealId;
value = Value;
} }
public class Crew
{
public Meal[] AllocatedMeals {
get {
return new Meal[]{
new Meal(1085, 2),
new Meal(1086, 1) }; } }
public int AllocatedMealTotal {
get {
return this.AllocatedMeals.Sum(x => x.value); } }
}
then the following code
Dictionary<string,string> MealsAllocated = crew.AllocatedMeals.ToDictionary(x => x.mealId.ToString(), x => x.value.ToString());
return new JavaScriptSerializer().Serialize(
new {
Allocated = new {
Total = crew.AllocatedMealTotal,
Values = MealsAllocated } )
to get
"Allocated":{"Total":3,"Values":{"1085":"2","1086":"1"}}
I'm building/updating an EntityFramework EntityObject on runtime. I want to set the properties of the entity class, property names and values are coming from another source.
So I'm doing this;
public static EntityCollection<T> UpdateLocaleEntity<T>(EntityCollection<T> entityCollectionToUpdate, params ILocaleControl[] values) where T : EntityObject
{
foreach (var x in entityCollectionToUpdate)
{
Type t = typeof(T);
dynamic localeEntity = x;
string cultureCode = localeEntity.CultureCode;
for (int j = 0; j < values.Length; j++)
{
var value = values[j].GetLocaleValue(cultureCode);
t.GetProperty(values[j].EntityPropertyName).SetValue(localeEntity, value, null);
}
}
return entityCollectionToUpdate;
}
So, how can I get rid of "t.GetProperty(values[j].EntityPropertyName).SetValue(localeEntity, value, null);" part, is there a dynamic way of doing this?
Something like;
dynamicCastedLocaleEntity.GetProperty(values[j].EntityPropertyName) = value;
Thanks.
Long answer coming up.
Reflection is great in many situations, horrible in some but in almost all cases it's slow.
There are at least 4 different ways to set a property in .NET without having to use reflection.
I thought I demonstrate one of them: Using compiled expression trees. Note that the expression building is rather expensive too so that's why it's very important to cache the delegate one builds with it in a dictionary (for instance):
Expression Trees was introduced in .NET35 and is used for many things. Here I use them to build a property setter expression and then compile it into a delegate.
The example demonstrates different timing for the different cases but here are my numbers:
Control case (hard coded): 0.02s
Reflection: 1.78s
Expression Tree: 0.06s
using System;
using System.Linq.Expressions;
namespace DifferentPropertSetterStrategies
{
class TestClass
{
public string XY
{
get;
set;
}
}
class DelegateFactory
{
public static Action<object, object> GenerateSetPropertyActionForControl(
)
{
return (inst, val) => ((TestClass) inst).XY = (string) val;
}
public static Action<object, object> GenerateSetPropertyActionWithReflection(
Type type,
string property
)
{
var propertyInfo = type.GetProperty(property);
return (inst, val) => propertyInfo.SetValue (inst, val, null);
}
public static Action<object,object> GenerateSetPropertyActionWithLinqExpression (
Type type,
string property
)
{
var propertyInfo = type.GetProperty(property);
var propertyType = propertyInfo.PropertyType;
var instanceParameter = Expression.Parameter(typeof(object), "instance");
var valueParameter = Expression.Parameter(typeof(object), "value");
var lambda = Expression.Lambda<Action<object, object>> (
Expression.Assign (
Expression.Property (Expression.Convert (instanceParameter, type), propertyInfo),
Expression.Convert(valueParameter, propertyType)),
instanceParameter,
valueParameter
);
return lambda.Compile();
}
}
static class Program
{
static void Time (
string tag,
object instance,
object value,
Action<object, object > action
)
{
// Cold run
action(instance, value);
var then = DateTime.Now;
const int Count = 2000000;
for (var iter = 0; iter < Count; ++iter)
{
action (instance, value);
}
var diff = DateTime.Now - then;
Console.WriteLine ("{0} {1} times - {2:0.00}s", tag, Count, diff.TotalSeconds);
}
static void Main(string[] args)
{
var instance = new TestClass ();
var instanceType = instance.GetType ();
const string TestProperty = "XY";
const string TestValue = "Test";
// Control case which just uses a hard coded delegate
Time(
"Control",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionForControl ()
);
Time(
"Reflection",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionWithReflection (instanceType, TestProperty)
);
Time(
"Expression Trees",
instance,
TestValue,
DelegateFactory.GenerateSetPropertyActionWithLinqExpression(instanceType, TestProperty)
);
Console.ReadKey();
}
}
}
For FuleSnabel's answer, you can speed it up a lot (sometimes twice as fast in my tests). In some tests, it was just as fast as the Control solution:
public static Action<Object,Object> GenerateSetPropertyActionWithLinqExpression2(Type type, String property) {
PropertyInfo pi = type.GetProperty(property,BindingFlags.Instance|BindingFlags.Public);
MethodInfo mi = pi.GetSetMethod();
Type propertyType = pi.PropertyType;
var instance = Expression.Parameter(typeof(Object), "instance");
var value = Expression.Parameter(typeof(Object), "value");
var instance2 = Expression.Convert(instance, type);
var value2 = Expression.Convert(value, pi.PropertyType);
var callExpr = Expression.Call(instance2, mi, value2);
return Expression.Lambda<Action<Object,Object>>(callExpr, instance, value).Compile();
}
possibly not with EntityObject, but if you've had an ExpandoObject than you can do
dynamic entity = new ExpandoObject();
(entity as IDictionary<String, Object>)[values[j].EntityPropertyName] = value
The open source framework ImpromptuInterface has methods to invoke based on a string using the DLR rather than reflection and runs faster than reflection too.
Impromptu.InvokeSet(localeEntity, values[j].EntityPropertyName,value);
I'm afraid not. Any use of a dynamic object is baked-in at compile time. Any call which could vary at run-time has to be done using reflection.