How are treated nonpersistent data in DevExpress XAF? - c#

I need to create some queries and these queries will be used to create graphs in a dashboard. The queries are a lot of calculations and are nonpersistent classes.
First I created the class and only about this I have HPerformance_ListView and HPerformance_DetailView but I don't have a data provider to populate it. The system tries to populate it from EF context, that is not possible.
[NavigationItem]
[NonPersistent]
public class HPerformance
{
public decimal Valor { get; set; }
public decimal Meta { get; set; }
public decimal Percentual { get; set; }
}
And the query class
public class MetasVendas
{
public MetasVendas()
{
fromDate = DateTime.Now.AddMonths(-1);
toDate = DateTime.Now;
revenda = 0;
}
public DateTime fromDate { get; set; }
public DateTime toDate { get; set; }
public long revenda { get; set; }
public BindingList<HPerformance> _hPerformance()
{
var r = _calculoMetaEValor();
var rr = r.GroupBy(g => true).Select(s => new HPerformance()
{
Valor = s.Sum(v => v.TotalUSacess + v.TotalUSradio),
Meta = s.Sum(v => v.Meta),
Percentual = s.Sum(vv => vv.TotalUSacess + vv.TotalUSradio) / s.Sum(vv => vv.Meta)
});
return new BindingList<HPerformance>(rr.ToList());
}
In the dashboard controller this is the code that I don't know how to handle. My example doesn't work
public partial class DashboardDealerGoalExecute : ViewController<DashboardView>
{
void parametersViewItem_ControlCreated(object sender, EventArgs e)
{
DashboardViewItem viewItem = (DashboardViewItem)sender;
if (viewItem.Id == "HPerformance")
{
ListView _hPerformance = (ListView)viewItem.InnerView;
if (parameters != null && parameters.Dealer != null)
{
BindingList<HPerformance> hp =
new MetasVendas()
{
fromDate = parameters.FromDate,
toDate = parameters.ToDate,
revenda = parameters.Dealer.ID
}._hPerformance();
_hPerformance.CurrentObject = hp;
}
}
HPerformance is a dashboard item and is connected to HPerformance class (1st code). How do I setup HPerformance_ListView to be populated by _hPerformance() method?
Thanks,
Marco Castro

Related

Bind List instead list c# linq From multiple source

i have my dto
public class DocumentForListDto
{
public int Id { get; set; }
public string Title { get; set; }
public string SubmittedBy { get; set; }
public DateTime SubmittedAt { get; set; }
public List<AuditsUpdateForListDto> UpdatedDocuments { get; set; }
}
public class AuditsForListDto
{
public string FullName { get; set; }
public DateTime UpdatedAt { get; set; }
}
and this code in my controller :
var docs = await _repo.Doc.Get();
and i have this audit to save any action in database
var aud = await _repo.Audit.FindByPrimaryKey(Constants.Doc, documents.Select(x => x.Id).ToList());
and this mapper for map my doc to dto(content)
var contents = _mapper.Map<IEnumerable<DocumentForListDto>>(docs);
and this my foreach to bind from audit to contents (CreatedBy/CreatedAt && UpdateBy/UpdatedAt)
if (contents.Any() && contents.Count() > 0 && audits.Any() && audits.Count()
> 0)
{
foreach (var content in contents)
{
//Search here by create Action
foreach (var audit in audits.Where(x =>
Convert.ToInt32(Regex.Match(x.PrimaryKey, #"\d+").Value) ==
content.Id && x.Type.Equals(Constants.Create)))
{
content.SubmittedBy = string.Concat(audit.User.FirstName, " ",
audit.User.LastName);
content.SubmittedAt = audit.DateTime;
}
}
//Here I need to bind list of Updated By and Updated At But I try many times but I don't find the right solution
}
i need to bind list of Updated By and Updated At i try with many logics but without success ??

Conversion of this SQL Query to LINQ

SELECT
CreationUtcTime, Speed,
CONVERT(varchar, (CreationUtcTime - LAG(CreationUtcTime) OVER (ORDER BY CreationUtcTime)), 108) AS diff
FROM
assetstatusrecords
WHERE
Speed <> 0.00
ORDER BY
CreationUtcTime
I want this SQL query to be converted to LINQ query without using LINQTODB functions and I want exact difference including hours, days, seconds, minutes such that I want to sum the time at later stage.
What I have tried is below:
var records = _context.AssetStatusRecords
.OrderByDescending(s => s.CreationUtcTime)
.Where(s => s.AssetId.Equals(asset.Id)
&& s.CreationUtcTime >= from
&& s.CreationUtcTime <= to
&& s.Speed != 0)
.ToList();
var query = from rec1 in records
from rec2 in records.Where(r => rec1.SequentialId > r.SequentialId).DefaultIfEmpty()
group new { rec1, rec2 } by new { rec1.SequentialId, rec1.CreationUtcTime, rec1.Speed } into g
orderby g.Key.SequentialId
select new
{
g.Key.CreationUtcTime,
g.Key.Speed,
Diff = EntityFunctions.DiffDays(g.Max(p => p.rec2.CreationUtcTime), g.Key.CreationUtcTime)
};
Model class for LINQ
class AssetStatusRecord : Entity
{
protected AssetStatusRecord()
{
}
public AssetStatusRecord(CoordinatesValue coordinates, double speed,
LengthValue distanceTravelled, Guid sensorId, Guid? assetId,
int? heading, Guid readingId, DateTime? sensorDateTime)
{
Coordinates = coordinates;
Speed = speed;
DistanceTravelled = distanceTravelled;
SensorId = sensorId;
AssetId = assetId;
Heading = heading;
ReadingId = readingId;
SensorDateTime = sensorDateTime;
}
public CoordinatesValue Coordinates { get; private set; }
public double Speed { get; private set; }
public LengthValue DistanceTravelled { get; private set; }
public Guid SensorId { get; private set; }
public Guid? AssetId { get; private set; }
public int? Heading { get; private set; }
public Guid ReadingId { get; private set; }
public DateTime? SensorDateTime { get; private set; }
}
And the Entity class is as follows:
public class Entity : IEntity
{
public Entity();
public Guid Id { get; protected set; }
public long SequentialId { get; protected set; }
public DateTime CreationUtcTime { get; protected set; }
public DateTime CreationLocalTime { get; protected set; }
}
And this is the interface IEntity:
public interface IEntity
{
Guid Id { get; }
long SequentialId { get; }
DateTime CreationUtcTime { get; }
}
Try the following query:
var records = _context.AssetStatusRecords
.Where(s => s.AssetId == asset.Id
&& s.CreationUtcTime >= from
&& s.CreationUtcTime <= to
&& s.Speed != 0);
var query =
from current in records
from prev in records
.Where(prev => current.CreationUtcTime <= prev.CreationUtcTime && prev.SequentialId < current.SequentialId)
.OrderByDescending(prev => prev.CreationUtcTime)
.Take(1)
.DefaultIfEmpty()
orderby current.CreationUtcTime
select new
{
current.CreationUtcTime,
current.Speed,
Diff = EntityFunctions.DiffDays(current.CreationUtcTime, prev.CreationUtcTime)
};

How to use lambda expression to access correct data type?

I am using lambda expression to access values with data type, but the problem I have data type for Time as Time(7) on my local database and using Entity Framework. On my model this data type is define as DateTime.
How do I now access this data type to be time?
This is my code:
public List GetIncident_Details()
{
Entities incident = new Entities();
List result = new List();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occurred = cData.Date_Occurred;
// How do I change this to have access?
// It's complaining about the data type object being set to a string?
model.Time = cData.Time;
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occurred { get; set; }
public DateTime Time { get; set; } // Time
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
Took some advice from #alexey-rumyantsev, then had to test my code by interrogating model data type for Time it was Date Time, then change to Timespan. While testing this data type compare to my local database record and it was passing correct vales when debugging.
// Model name
public class Incident_DropDown
{
public string Title { get; set; }
public string Description { get; set; }
public string Date_Occured { get; set; }
public TimeSpan Time { get; set; } // had to change to work
public string Assignment_Group { get; set; }
public string Reported_CI { get; set; }
}
// Controller
public List<Incident_DropDown> GetIncident_Details()
{
Entities incident = new Entities();
List<Incident_DropDown> result = new List<Incident_DropDown>();
var c_incident = incident.Incident_Template.Select(c => c).ToList();
if (c_incident != null && c_incident.Count() > 0)
{
foreach (var cData in c_incident)
{
Incident_DropDown model = new Incident_DropDown();
model.Title = cData.Title;
model.Description = cData.Description;
model.Date_Occured = cData.Date_Occured;
model.Time = cData.Time; // This here enable to pass correct time as per database record
model.Assignment_Group = cData.Assignment_Group;
model.Reported_CI = cData.Reported_CI;
result.Add(model);
}
}
return result;
}

Resampling with Deedle duplicate keys

My code below resamples 5-minute interval to 1-day interval for the daily profit stats. The problem is that BacktestResult consists of duplicate CloseDate values, because I'm testing with multiple pairs (TRXUSDT, ETHUSDT and BTCUSDT). dailyProfit returns Series<DateTime, double>, which explains the exception. How can I make it grouped by Pair or something? It works fine when tested with one pair.
// Create series
var series = _backtestResults.ToOrdinalSeries();
// daily_profit = results.resample('1d', on = 'close_date')['profit_percent'].sum()
var dailyProfit = series.ResampleEquivalence(
index => new DateTime(series[index].CloseDate.Year, series[index].CloseDate.Month, series[index].CloseDate.Day, 0, 0, 0, DateTimeKind.Utc),
group => group.SelectValues(g => g.ProfitPercentage).Sum()).DropMissing();
// classes
public class BacktestResult
{
public string Pair { get; set; }
public decimal ProfitPercentage { get; set; }
public decimal ProfitAbs { get; set; }
public decimal OpenRate { get; set; }
public decimal CloseRate { get; set; }
public DateTime OpenDate { get; set; }
public DateTime CloseDate { get; set; }
public decimal OpenFee { get; set; }
public decimal CloseFee { get; set; }
public decimal Amount { get; set; }
public decimal TradeDuration { get; set; }
public SellType SellReason { get; set; }
}
Edit:
Example which takes the JSON data from pastebin:
using Deedle;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
namespace Resample
{
class Program
{
public class BacktestResultTest
{
public string Pair { get; set; }
public decimal ProfitPercentage { get; set; }
public decimal ProfitAbs { get; set; }
public decimal OpenRate { get; set; }
public decimal CloseRate { get; set; }
public DateTime OpenDate { get; set; }
public DateTime CloseDate { get; set; }
public decimal OpenFee { get; set; }
public decimal CloseFee { get; set; }
public decimal Amount { get; set; }
public decimal TradeDuration { get; set; }
public bool OpenAtEnd { get; set; }
public int SellReason { get; set; }
}
static void Main(string[] args)
{
// Take JSON data from pastebin
using var webClient = new WebClient();
var json = webClient.DownloadString("https://pastebin.com/raw/Dhp9202f");
// Deserialize the data
var data = JsonConvert.DeserializeObject<List<BacktestResultTest>>(json);
var ts = data.ToOrdinalSeries();
var byDateAndPair = ts.SelectKeys(kvp => Tuple.Create(kvp.Value.Value.CloseDate, kvp.Value.Value.Pair)).SortByKey();
// daily_profit = results.resample('1d', on = 'close_date')['profit_percent'].sum()
var dailyProfit2 = byDateAndPair.ResampleEquivalence(
k => Tuple.Create(new DateTime(k.Item1.Year, k.Item1.Month, k.Item1.Day), k.Item2),
g => g.Select(kvp => kvp.Value.ProfitPercentage).Sum());
// backtest_worst_day = min(daily_profit)
var worstDay2 = dailyProfit2.Min();
// backtest_best_day = max(daily_profit)
var bestDay2 = dailyProfit2.Max();
// winning_days = sum(daily_profit > 0)
var winningDays2 = dailyProfit2.SelectValues(x => x > 0).Sum();
// draw_days = sum(daily_profit == 0)
var drawDays2 = dailyProfit2.SelectValues(x => x == 0).Sum();
// losing_days = sum(daily_profit < 0)
var losingDays2 = dailyProfit2.SelectValues(x => x < 0).Sum();
Console.ReadLine();
}
}
}
You can use a custom data type as a key in Deedle. If you want to be able to use resampling on the series, then this needs to support IComparable. You can either define your own type or use built-in Tuple.
Assuming we have some very basic data:
var ts =
new[] {
KeyValue.Create(new DateTime(2020,1,1), new { Value = 1.0, Kind = "A" }),
KeyValue.Create(new DateTime(2020,1,2), new { Value = 1.0, Kind = "A" }),
KeyValue.Create(new DateTime(2020,1,3), new { Value = 1.0, Kind = "B" }),
KeyValue.Create(new DateTime(2020,1,4), new { Value = 1.0, Kind = "B" }),
}.ToSeries();
The first thing we need to do is to change the key to be the date together with a kind. (In fact, you can get into trouble earlier in your code if you had duplicate dates!)
var byDateAndKind =
ts.SelectKeys(kvp => Tuple.Create(kvp.Key, kvp.Value.Value.Kind)).SortByKey();
Now the key is Tuple<DateTime, string> consisting of the date and the kind. You can now use ResampleEquivalence on this. Here, we use year and kind as the new key and sum values in group:
var aggByYearAndKind =
byDateAndKind.ResampleEquivalence(
(k) => Tuple.Create(k.Item1.Year, k.Item2),
(g) => g.Select(kvp => kvp.Value.Value).Sum());
aggByYearAndKind.Print();
This will print a series that maps 2020, "A" to 2 and also 2020, "B" to 2.
EDIT You are right - this does not seem to work. I was able to get it to work using GroupBy instead of ResampleEquvialence:
var dailyProfit2 =
ts.GroupBy(kvp =>
new { Date = new DateTime(kvp.Value.CloseDate.Year, kvp.Value.CloseDate.Month, kvp.Value.CloseDate.Day), Kind = kvp.Value.Pair })
.SelectValues(g => g.Select(kvp => kvp.Value.ProfitPercentage).Values.Sum());
// backtest_worst_day = min(daily_profit)
var worstDay2 = dailyProfit2.Min();
// backtest_best_day = max(daily_profit)
var bestDay2 = dailyProfit2.Max();
// winning_days = sum(daily_profit > 0)
var winningDays2 = dailyProfit2.Where(x => x.Value > 0).Values.Sum();
// draw_days = sum(daily_profit == 0)
var drawDays2 = dailyProfit2.Where(x => x.Value == 0).Values.Sum();
// losing_days = sum(daily_profit < 0)
var losingDays2 = dailyProfit2.Where(x => x.Value < 0).Values.Sum();

Adding data from one list to another using linq

I need to populate a dropdown in my UI and hence added List object to the view model in my c# application. I am fetching the data in my controller code for the dropdown. What's the best way to assign data to the viewmodel object. Is linq an option?
I basically need to assign fundclasses to fundTrackRecord.FundClass
The main Viewmodel:
public class FundPerformanceVM
{
public FundPerformanceVM()
{
TrackRecord = new List<TrackRecordVM>();
}
public int FundId { get; set; }
public string FundName { get; set; }
public List<FundClassVM> FundClass { get; set; }
public string BenchmarkName1 { get; set; }
public string BenchmarkName2 { get; set; }
public List<TrackRecordVM> TrackRecord { get; set; }
public List<Tuple<string, string, string>> FundStatistics { get; set; }
}
public class FundClassVM
{
public int FundClassId { get; set; }
public string FundClass { get; set; }
}
Controller code:
var service = GetViewService<V_LEGAL_FUND_CLASS_SUMMARY>();
foreach (KeyValuePair<int, IEnumerable<FUND_PERFORMANCE>> entry in allPerformance)
{
var fundClasses = service.GetAll().Where(x => x.FUND_ID == entry.Key).Select(x => new { x.LEGAL_FUND_CLASS_ID, x.LEGAL_FUND_CLASS}).ToList();
var fundTrackRecord = new FundPerformanceVM();
fundTrackRecord.FundClass = ??;
If I understood correctly the structure of your model, you can try this:
fundTrackRecord.FundClass = fundClasses.Select(fc => new FundClassVM
{
FundClassId = fc.LEGAL_FUND_CLASS_ID,
FundClass = fc.LEGAL_FUND_CLASS
}).ToList();
You can also do this directly, replacing the code:
var fundClasses = service.GetAll().Where(x => x.FUND_ID == entry.Key).Select(x => new { x.LEGAL_FUND_CLASS_ID, x.LEGAL_FUND_CLASS}).ToList();
var fundTrackRecord = new FundPerformanceVM();
With:
var fundTrackRecord = new FundPerformanceVM();
fundTrackRecord.FundClass = service.GetAll().
Where(x => x.FUND_ID == entry.Key).
Select(fc => new FundClassVM
{
FundClassId = fc.LEGAL_FUND_CLASS_ID,
FundClass = fc.LEGAL_FUND_CLASS
}).ToList();

Categories

Resources