I am trying to optimise the number of fields I return from a query when doing joins.
However, there is something wrong with enums.
var query = db.From<Models.Traffic>()
.Join<Models.Consumer>((traffic, consumer) => traffic.ConsumerId == consumer.Id)
.Where(q => q.CampaignId == id)
.Select<Models.Traffic, Models.Consumer>((traffic, consumer) =>
new
{
traffic.CreateDate,
Value = traffic.CouponValue,
ConsumerName = consumer.FirstName,
ConsumerChannel = consumer.LoginProvider
});
var results = db.Select<(DateTime CreateDate, decimal Value, string ConsumerName, Models.Enums.LoginProvider ConsumerChannel)>(query);
foreach (var result in results)
{
var data = new Data()
{
result.CreateDate,
result.Value,
result.ConsumerName,
result.ConsumerChannel,
};
response.Add(data);
}
public enum LoginProvider
{
Facebook,
Twitter,
Google,
}
public class Consumer : IHasId<Guid>
{
[PrimaryKey] public Guid Id { get; set; }
public LoginProvider LoginProvider { get; set; }
public string FirstName { get; set; }
}
Note: objects simplified for this example
So the issue is that the result.ConsumerChannel is always the first item from the enum Facebook. If I use string as datatype for the ConsumerChannel then the value is always NULL.
I tried to add the 4.5.1 packages but then get an error:
System.MissingMethodException: Method not found: 'Boolean ServiceStack.PlatformExtensions.HasAttributeCached(System.Reflection.MemberInfo)'.
at at ServiceStack.OrmLite.SqlServer.Converters.SqlServerJsonStringConverter.ToDbValue(Type fieldType, Object value)
at at ServiceStack.OrmLite.OrmLiteDialectProviderBase`1.GetFieldValue(Type fieldType, Object value)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.SetParamValue(IOrmLiteDialectProvider dialectProvider, IDbDataParameter p, Object value, Type propType, FieldDefinition fieldDef)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.<>c__DisplayClass12_0.<SetParameters>b__0(String propName, String columnName, Object value)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.ForEachParam(Dictionary`2 values, ModelDefinition modelDef, Boolean excludeDefaults, ParamIterDelegate fn)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.SetParameters(IDbCommand dbCmd, Type type, Object anonType, Boolean excludeDefaults, String& sql)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.SetParameters[T](IDbCommand dbCmd, Object anonType, Boolean excludeDefaults, String& sql)
at at ServiceStack.OrmLite.OrmLiteReadCommandExtensions.SqlScalar[T](IDbCommand dbCmd, String sql, Object anonType)
at at ServiceStack.OrmLite.OrmLiteReadApi.<>c__DisplayClass54_0`1.<SqlScalar>b__0(IDbCommand dbCmd)
at at ServiceStack.OrmLite.OrmLiteExecFilter.Exec[T](IDbConnection dbConn, Func`2 filter)
at at ServiceStack.OrmLite.OrmLiteReadExpressionsApi.Exec[T](IDbConnection dbConn, Func`2 filter)
at at ServiceStack.OrmLite.OrmLiteReadApi.SqlScalar[T](IDbConnection dbConn, String sql, Object anonType)
at at ServiceStack.OrmLite.SqlServer.SqlServerOrmLiteDialectProvider.DoesColumnExist(IDbConnection db, String columnName, String tableName, String schema)
I do some extra things upon startup where I use attributes on properties to do something extra. But it seems that the DoesColumnExist is not working anymore?
Also can you provide a stand-alone repro that fails, I wasn’t able to repro the issue using this code:
db.DropAndCreateTable<Traffic>();
db.DropAndCreateTable<Consumer>();
var id = 1;
var t = new Traffic { ConsumerId = Guid.NewGuid(), CreateDate = DateTime.UtcNow, CampaignId = 1, CouponValue = 333.33m };
db.Insert(t);
var c = new Consumer {Id = t.ConsumerId, FirstName = "FirstName", LoginProvider = LoginProvider.Twitter };
db.Insert(c);
var query = db.From<Traffic>()
.Join<Consumer>((traffic, consumer) => traffic.ConsumerId == consumer.Id)
.Where(q => q.CampaignId == id)
.Select<Traffic, Consumer>((traffic, consumer) =>
new
{
traffic.CreateDate,
Value = traffic.CouponValue,
ConsumerName = consumer.FirstName,
ConsumerChannel = consumer.LoginProvider
});
var results = db.Select<(DateTime CreateDate, decimal Value, string ConsumerName, LoginProvider ConsumerChannel)>(query);
results.PrintDump();
and these types:
class Traffic
{
[AutoIncrement]
public int Id { get; set; }
public Guid ConsumerId { get; set; }
public DateTime CreateDate { get; set; }
public decimal CouponValue { get; set; }
public int CampaignId { get; set; }
}
public enum LoginProvider
{
Facebook,
Twitter,
Google,
}
public class Consumer : IHasId<Guid>
{
[PrimaryKey] public Guid Id { get; set; }
public LoginProvider LoginProvider { get; set; }
public string FirstName { get; set; }
}
Ok will try to do that; meantime switched back to a POCO for the results which is also working fine including only retrieving the fields that are defined in the poco. But will try to make a new solution to test.