Columns not created - subsonic

I'm using Subsonic (SimpleRepository) in my new project and enjoy using it but...
With one, and only one of my table, it does not create all the columns and i don't understand why.
Here is the code :
public class Rating
{
public Rating()
{
UsernameVotant = "";
UsernameEvaluate = "";
Note = 0.0;
NoteAccueil = 0.0;
NotePedagogie = 0.0;
NoteRapportQP = 0.0;
NoteContenu = 0.0;
Comment = "";
stageId = 0;
DateNote = DateTime.Now;
isValidate = false;
}
[SubSonicPrimaryKey]
public int ID { get; set; }
public DateTime DateNote;
public int stageId;
public string UsernameVotant;
public string UsernameEvaluate;
public int Note;
public int NoteAccueil;
public double NotePedagogie;
public double NoteRapportQP;
public double NoteContenu;
[SubSonicLongString]
public string Comment { get; set; }
public bool isValidate { get; set; }
}
Called like my other classes :
IRepository _repoRun = new SimpleRepository(Core.Config.ArticlesDB, SimpleRepositoryOptions.RunMigrations);
public bool AddRating(Rating p)
{
_repoRun.Add<Rating>(p);
return true;
}
The table Ratings created contains the columns :
ID, Comment, isValidate
Whatever what I try to add as default value, the 3 columns contains the value :
ID = 1 (2, 3, 4...) -> works
Comment = ""
isValidate = false
As i noticed a probleme where naming a column "Read", i tryed to rename the columns, rename the table (which was "Vote" [in french]) but the probleme is the same as with my original table "Votes"
Could you help me please.
Thanks in advance (and sorry for my english)

The only properties you're defining in that class are ID, Comment and isValidate so these are the only columns SubSonic will generate. Change your fields to properties and SubSonic should create columns for them:
[SubSonicPrimaryKey]
public int ID { get; set; }
public DateTime DateNote { get; set; }
public int StageId { get; set; }
public string UsernameVotant { get; set; }
public string UsernameEvaluate { get; set; }
public int Note { get; set; }
public int NoteAccueil { get; set; }
public double NotePedagogie { get; set; }
public double NoteRapportQP { get; set; }
public double NoteContenu { get; set; }
[SubSonicLongString]
public string Comment { get; set; }
public bool IsValidate { get; set; }

Related

Selecting OrmLite new object from joined table for insertion

I have 3 entities:
[CompositeIndex(nameof(Url), nameof(TargetDomainRecordId), nameof(UserAuthCustomId), Unique = true)]
public class WatchedUrlRecord
{
[AutoIncrement]
public long Id { get; set; }
public string Url { get; set; }
public string Provider { get; set; }
public string DomainKey { get; set; }
public WatchedUrlScanStatus WatchedUrlScanStatus { get; set; }
public bool NoFollow { get; set; }
public HttpStatusCode HttpStatusCode { get; set; }
public DateTime? LastScanTime { get; set; }
public WatchedUrlScanResult LastScanData { get; set; }
public string Anchors { get; set; }
public int? OutboundLinks { get; set; }
[ForeignKey(typeof(TargetDomainRecord), OnDelete = "CASCADE")]
public long TargetDomainRecordId { get; set; }
[ForeignKey(typeof(UserAuthCustom), OnDelete = "CASCADE")]
public long UserAuthCustomId { get; set; }
}
[CompositeIndex(nameof(Url), nameof(TargetDomainRecordId), nameof(UserAuthCustomId), Unique = true)]
public class WatchedUrlQueue
{
[PrimaryKey]
public long WatchedUrlRecordId { get; set; }
[Index]
public string Url { get; set; }
[Index]
public string DomainKey { get; set; }
[Index]
public long TargetDomainRecordId { get; set; }
public string TargetDomainKey { get; set; }
[Index]
public DateTime CreateDate { get; set; } = DateTime.UtcNow;
public int Tries { get; set; }
[Index]
public DateTime? DeferUntil { get; set; }
[Index]
public long UserAuthCustomId { get; set; }
[Index]
public bool FirstScan { get; set; }
}
[CompositeIndex(nameof(Url), nameof(UserAuthCustomId), Unique = true)]
public class TargetDomainRecord
{
[AutoIncrement]
public long Id { get; set; }
public string Url { get; set; }
public string DomainKey { get; set; }
public DateTime CreateDate { get; set; } = DateTime.Now;
public DateTime? DeleteDate { get; set; }
public bool IsDeleted { get; set; }
public bool Active { get; set; } = true;
public DomainType DomainType { get; set; }
[ForeignKey(typeof(UserAuthCustom), OnDelete = "CASCADE")]
public long UserAuthCustomId { get; set; }
}
I am trying to insert queue objects based on IDs of WatchedUrlRecords so I came up with this query:
var q = db.From<WatchedUrlRecord>()
.Where(x => Sql.In(x.Id, ids))
.Join<TargetDomainRecord>((w, t) => w.TargetDomainRecordId == t.Id)
.Select<WatchedUrlRecord, TargetDomainRecord>((w, t) => new WatchedUrlQueue()
{
UserAuthCustomId = w.UserAuthCustomId,
DomainKey = w.DomainKey,
CreateDate = DateTime.UtcNow,
DeferUntil = null,
FirstScan = firstScan,
TargetDomainKey = t.DomainKey,
Tries = 0,
TargetDomainRecordId = w.TargetDomainRecordId,
Url = w.Url,
WatchedUrlRecordId = w.Id
});
var inserted = db.InsertIntoSelect<WatchedUrlQueue>(q, dbCmd => dbCmd.OnConflictIgnore());
This doesn't work and gives error:
variable 'w' of type 'Project.ServiceModel.WatchedUrl.Entities.WatchedUrlRecord' referenced from scope '', but it is not defined
If I try anonymous object like new {} instead of new WatchedUrlQueue then InsertIntoSelect() throws error:
'watched_url_record"."user_auth_custom_id' is not a property of 'WatchedUrlQueue'
I have looked in documentation and can see SelectMulti() method but I don't think that is suitable as it will involve me creating a tuple list to combine into the new object. The passed list can be quite large so I just want to send the correct SQL statement to PostgreSQL which would be along lines of:
insert into watched_url_queue (watched_url_record_id, url, domain_key, target_domain_record_id, target_domain_key, create_date, tries, defer_until, user_auth_custom_id)
select wur.id watched_url_record_id,
wur.url url,
wur.domain_key,
wur.target_domain_record_id,
tdr.domain_key,
'{DateTime.UtcNow:MM/dd/yyyy H:mm:ss zzz}' create_date,
0 tries,
null defer_until,
wur.user_auth_custom_id
from watched_url_record wur
join target_domain_record tdr on wur.target_domain_record_id = tdr.id
where wur.id in (323,3213123,312312,356456)
on conflict do nothing ;
I currently have a lot of similar type queries in my app and it is causing extra work maintaining them, would be really nice to be able to have them use fluent api without reducing performance. Is this possible?
Custom select expression can't be a typed projection (i.e. x => new MyType { ... }), i.e. you'd need to use an anonymous type expression (i.e. new { ... }) which captures your query's Custom SELECT Projection Expression.
You'll also need to put your JOIN expressions directly after FROM (as done in SQL) which tells OrmLite it needs to fully qualify subsequent column expressions like Id which would otherwise be ambiguous.
I've resolved an issue with field resolution of custom select expressions in this commit where your query should now work as expected:
var q = db.From<WatchedUrlRecord>()
.Join<TargetDomainRecord>((w, t) => w.TargetDomainRecordId == t.Id)
.Where(x => Sql.In(x.Id, ids))
.Select<WatchedUrlRecord, TargetDomainRecord>((w, t) => new {
UserAuthCustomId = w.UserAuthCustomId,
DomainKey = w.DomainKey,
CreateDate = DateTime.UtcNow,
DeferUntil = (DateTime?) null,
FirstScan = firstScan,
TargetDomainKey = t.DomainKey,
Tries = 0,
TargetDomainRecordId = w.TargetDomainRecordId,
Url = w.Url,
WatchedUrlRecordId = w.Id
});
var inserted = db.InsertIntoSelect<WatchedUrlQueue>(q, dbCmd=>dbCmd.OnConflictIgnore());
This change is available from v5.10.5 that's now available on MyGet.

How can I populate the datagrid cobmo box column in WPF?

I am having problems populating data grid combo box column with combo boxes, the data grid column is not showing any data. But, first things first. Here are my binding classes:
public class StartingEleven
{
public string name { get; set; }
public int shirt_number { get; set; }
public string position { get; set; }
public bool captain { get; set; }
}
public class DGObject
{
public string FifaID { get; set; }
public string Venue { get; set; }
public string Location { get; set; }
public DateTime Date { get; set; }
public int Goals { get; set; }
public int Penalties { get; set; }
public string AwayTeamCode { get; set; }
public int GuestGoals { get; set; }
public List<StartingEleven> HomeTeam11 { get; set; }
}
And my root object:
public class RootObject
{
public string venue { get; set; }
public string location { get; set; }
public string status { get; set; }
public string time { get; set; }
public string fifa_id { get; set; }
public Weather weather { get; set; }
public string attendance { get; set; }
public List<string> officials { get; set; }
public string stage_name { get; set; }
public string home_team_country { get; set; }
public string away_team_country { get; set; }
public DateTime datetime { get; set; }
public string winner { get; set; }
public string winner_code { get; set; }
public HomeTeam home_team { get; set; }
public AwayTeam away_team { get; set; }
public List<HomeTeamEvent> home_team_events { get; set; }
public List<AwayTeamEvent> away_team_events { get; set; }
public HomeTeamStatistics home_team_statistics { get; set; }
public AwayTeamStatistics away_team_statistics { get; set; }
public DateTime last_event_update_at { get; set; }
public DateTime last_score_update_at { get; set; }
}
There is a saying: a single picture is worth a thousand words... So, to be more accurate, first, here is my output that I am having problems with:
Here is my method that loads this datagrid:
public static void LoadAllEventsForHomeTeam(System.Windows.Controls.ComboBox cb, System.Windows.Controls.DataGrid dg)
{
var url = new Url("http://worldcup.sfg.io/matches/country?fifa_code=");
string urlEndpoint = GetItemFromComboBoxWpf(cb);
var request = url + urlEndpoint;
string cbItem = cb.SelectedItem.ToString();
System.Windows.Controls.DataGridTextColumn c1 = new System.Windows.Controls.DataGridTextColumn();
c1.Header = "Game ID";
c1.Binding = new System.Windows.Data.Binding("FifaID");
c1.Width = 120;
dg.Columns.Add(c1);
System.Windows.Controls.DataGridTextColumn c2 = new System.Windows.Controls.DataGridTextColumn();
c2.Header = "City";
c2.Binding = new System.Windows.Data.Binding("Venue");
c2.Width = 95;
dg.Columns.Add(c2);
System.Windows.Controls.DataGridTextColumn c3 = new System.Windows.Controls.DataGridTextColumn();
c3.Header = "Location";
c3.Binding = new System.Windows.Data.Binding("Location");
c3.Width = 150;
dg.Columns.Add(c3);
System.Windows.Controls.DataGridTextColumn c4 = new System.Windows.Controls.DataGridTextColumn();
c4.Header = "Date";
c4.Binding = new System.Windows.Data.Binding("Date");
c4.Width = 180;
dg.Columns.Add(c4);
System.Windows.Controls.DataGridTextColumn c5 = new System.Windows.Controls.DataGridTextColumn();
c5.Header = "Goals";
c5.Binding = new System.Windows.Data.Binding("Goals");
c5.Width = 75;
dg.Columns.Add(c5);
System.Windows.Controls.DataGridTextColumn c6 = new System.Windows.Controls.DataGridTextColumn();
c6.Header = "Penalties";
c6.Binding = new System.Windows.Data.Binding("Penalties");
c6.Width = 100;
dg.Columns.Add(c6);
System.Windows.Controls.DataGridTextColumn c7 = new System.Windows.Controls.DataGridTextColumn();
c7.Header = "Guest";
c7.Binding = new System.Windows.Data.Binding("AwayTeamCode");
c7.Width = 90;
dg.Columns.Add(c7);
System.Windows.Controls.DataGridTextColumn c8 = new System.Windows.Controls.DataGridTextColumn();
c8.Header = "Guest score";
c8.Binding = new System.Windows.Data.Binding("GuestGoals");
c8.Width = 110;
dg.Columns.Add(c8);
System.Windows.Controls.DataGridComboBoxColumn c9 = new System.Windows.Controls.DataGridComboBoxColumn();
c9.Header = "Team 11";
c9.TextBinding = new System.Windows.Data.Binding("HomeTeam11");
c9.Width = 110;
dg.Columns.Add(c9);
try
{
Dispatcher.CurrentDispatcher.BeginInvoke(new Action(async () =>
// await Task.Run(async () =>
{
if (request != null)
{
List<Teams.RootObject> matches = await request.GetJsonAsync<List<Teams.RootObject>>();
foreach (var match in matches)
{
if (cbItem.Contains(match.home_team.code))
{
dg.Items.Add(new Teams.DGObject
{
FifaID = match.fifa_id,
Venue = match.venue,
Location = match.location,
Date = match.datetime.ToLocalTime(),
Goals = match.home_team.goals,
Penalties = match.home_team.penalties,
AwayTeamCode = match.away_team.code,
GuestGoals = match.away_team.goals,
HomeTeam11 = match.home_team_statistics.starting_eleven
});
}
}
}
}));
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
As you can see, this method loads datagrid with events which are soccer matches for selected team. By selecting an item from combo box, here named cb, a method forms an API call by completing an API call with selected combo box item as endpoint thus loading datagrid with matches that Germany played as a home team. Now, here is the problem: Last column, here named Team11 should contain combo boxes, and combo boxes should contain eleven players (starting eleven) that played that match. Selected team, in this case Germany, obviously, played four matches as home team. So, in column Team11 there should be four comboboxes, one for each game, placed in each row, and each combobox should contain eleven players that played that particular match, but there is no data in column Team11. Any ideas? Thank you.

How to perform a more complex query with AutoQuery

Given the following definitions from a ServiceStack endpoint:
public class LoanQueue
{
public int LoanId { get; set; }
public DateTime Submitted { get; set; }
public DateTime Funded { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public int Fico { get; set; }
public int Fraud { get; set; }
public int CDS { get; set; }
public int IDA { get; set; }
public string Income { get; set; }
public string Liabilities { get; set; }
public string Agent { get; set; }
public string Status { get; set; }
public string State { get; set; }
public string Product { get; set; }
public string Comment { get; set; }
}
public enum DateType
{
None,
Submitted,
Funded
}
[Route("/loan/queue/search", "GET")]
public class LoanQueueQueryGet : QueryBase<LoanQueue>
{
public DateType DateType { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public string AgentUserName { get; set; }
public Languange Languange { get; set; }
public bool WorkingLoan { get; set; }
public bool MicrobusinessLoan { get; set; }
public LoanStatus LoanStatus { get; set; }
}
public object Get(LoanQueueQueryGet request)
{
if (request == null) throw new ArgumentNullException("request");
var profiler = Profiler.Current;
using (profiler.Step("LoanServices.LoanQueue"))
{
SqlExpression<LoanQueue> q = AutoQuery.CreateQuery(request, Request.GetRequestParams());
QueryResponse<LoanQueue> loanQueueResponse = AutoQuery.Execute(request, q);
return loanQueueResponse;
}
}
My question is this, "Is it even possible to run conditional logic based on the request object in the service impl"? e.g.
If DateType == DateType.Submitted
then query the Submitted property on the LoanQueue with a BETWEEN clause (StartDate/EndDate) or
If DateType == DateType.Funded
then query the Funded property on the LoanQueue with a BETWEEN clause (StartDate/EndDate).
My guess is that I'm trying to bend AutoQuery too far and would be better served just coding it up the old fashion way. I really like the baked-in features of the AutoQuery plugin and I'm sure there will be times when it will suit my needs.
Thank you,
Stephen
AutoQuery will ignore any unmatched fields so you're able to use them to extend your populated AutoQuery with additional custom logic, e.g:
public object Get(LoanQueueQueryGet request)
{
var q = AutoQuery.CreateQuery(request, Request.GetRequestParams());
if (request.DateType == DateType.Submitted)
{
q.And(x => x.Submitted >= request.StartDate && x.Submitted < request.EndDate);
}
else
{
q.And(x => x.Funded >= request.StartDate && x.Funded < request.EndDate);
}
var loanQueueResponse = AutoQuery.Execute(request, q);
return loanQueueResponse;
}

assigning dates to entity fields during linq selects

I'm have a domain service for a LS application that selects rows and many of the fields in the row are datetime fields. I keep getting Linq to Entity errors about the date time conversion when I try to do the following code:
public IQueryable<riaProjectItem> FilterProjectItems(int? projID)
{
var FilteredProjectItems = _
from pi in this.Context.ProjectItems
where (pi.Project.Id == projID)
orderby pi.ItemCode ascending
select new riaProjectItem
{
// Note we turn the ID of the Internal Products to
// A negative number so we don't have duplicates
// with the External products
Id = pi.Id,
ItemCode = pi.ItemCode,
ItemName = pi.ItemName,
TechnicalStartDate = pi.TechnicalStartDate.GetValueOrDefault().Date,
TechnicalWeeks = Convert.ToDecimal(pi.TechnicalWeeks.ToString()),
TechnicalPercentComplete = Convert.ToDecimal(pi.TechnicalPercentComplete.ToString()),
EditingStartProjected = pi.EditingStartProjected.GetValueOrDefault().Date,
EditingStartActual = pi.EditingStartActual.GetValueOrDefault().Date,
EditingWordWeeks = Convert.ToDecimal(pi.EditingWordWeeks.ToString()),
EditingEditPercent = Convert.ToDecimal(pi.EditingEditPercent.ToString()),
EditingReview = Convert.ToDecimal(pi.EditingReview.ToString()),
ClientReviewStartProjected = pi.ClientReviewStartProjected.GetValueOrDefault().Date,
ClientReviewStartActual = pi.ClientReviewStartActual.GetValueOrDefault().Date,
TranslationPercent = Convert.ToDecimal(pi.TranslationPercent.ToString()),
ClientReview = Convert.ToDecimal(pi.ClientReview.ToString()),
FinalStartProjected = pi.FinalStartProjected.GetValueOrDefault().Date,
FinalStartActual = pi.FinalStartActual.GetValueOrDefault().Date,
FinalForm = Convert.ToDecimal(pi.FinalForm.ToString()),
FinalReview = Convert.ToDecimal(pi.FinalReview.ToString()),
CBTStartDateProjected = pi.CBTStartDateProjected.GetValueOrDefault().Date,
CBTStartDateActual = pi.CBTStartDateActual.GetValueOrDefault().Date,
CBTWeeks = Convert.ToDecimal(pi.CBTWeeks.ToString()),
CBTPercent = Convert.ToDecimal(pi.CBTPercent.ToString()),
DeliveryDate = pi.DeliveryDate.GetValueOrDefault().Date,
ActualDeliveryDate = pi.ActualDeliveryDate.GetValueOrDefault().Date,
Comments = pi.Comments
} ;
return FilteredProjectItems;
}
// Override the Count method in order for paging to work correctly
protected override int Count<T>(IQueryable<T> query)
{
return query.Count();
}
}
Class riaProjectItem
public class riaProjectItem
{
[Key]
public int Id { get; set; }
public int ItemCode { get; set; }
public string ItemName { get; set; }
public DateTime TechnicalStartDate { get; set; }
public Decimal TechnicalWeeks { get; set; }
public decimal TechnicalPercentComplete { get; set; }
public DateTime EditingStartProjected { get; set; }
public DateTime EditingStartActual { get; set; }
public decimal EditingWordWeeks { get; set; }
public decimal EditingEditPercent { get; set; }
public decimal EditingReview { get; set; }
public DateTime ClientReviewStartProjected { get; set; }
public DateTime ClientReviewStartActual { get; set; }
public decimal TranslationPercent { get; set; }
public decimal ClientReview { get; set; }
public DateTime FinalStartProjected { get; set; }
public DateTime FinalStartActual { get; set; }
public decimal FinalForm { get; set; }
public decimal FinalReview { get; set; }
public DateTime CBTStartDateProjected { get; set; }
public DateTime CBTStartDateActual { get; set; }
public decimal CBTWeeks { get; set; }
public decimal CBTPercent { get; set; }
public DateTime DeliveryDate { get; set; }
public DateTime ActualDeliveryDate { get; set; }
public string Comments { get; set; }
}
How do I assign dates to the entity fields?
When I assign the field I do so like this:
TechnicalStartDate = (pi.TechnicalStartDate.HasValue) ? pi.TechnicalStartDate.Value : (DateTime)System.Data.SqlTypes.SqlDateTime.MinValue
You need to be clear you're using the SQL version of Min value and not the .NET value which is different.

SubSonic Simple Repository One-To-Many

I made a class like:
public class Video
{
public Guid VideoID { get; set; }
public VideoCategory VideoCategory { get; set; }
public int SortIndex { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string Author { get; set; }
public string Filename { get; set; }
public new void Add()
{
this.VideoID = Guid.NewGuid();
DB.Repository.Add(this);
}
}
And another like
public class VideoCategory
{
public Guid VideoCategoryID { get; set; }
public string Title { get; set; }
public new void Add()
{
this.VideoCategoryID = Guid.NewGuid();
DB.Repository.Add(this);
}
}
I then have code like:
VideoCategory VideoCategory = new VideoCategory();
VideoCategory.Title = "TestTitle";
VideoCategory.Add();
Video Video = new Video();
Video.VideoCategory = VideoCategory;
Video.SortIndex = 1;
Video.Title = "TestTitle";
Video.Body = "TestBody";
Video.Author = "TestAuthor";
Video.Filename = "TestFile.flv";
Video.Add();
It doesn't save the VideoCategory into my database, so obviously i'm missing something. What else is needed to done to save a one-to-many relationship?
You could probably just do the following, you'll probably want to tidy it up but it will ensure your foreign key value gets populated:
public class Video
{
protected VideoCategory videoCategory;
public Guid ID { get; set; }
public VideoCategory VideoCategory
{
get { return videoCategory; }
set
{
videoCategory = value;
VideoCategoryId = value.ID;
}
}
public Guid VideoCategoryId { get; set; }
public int SortIndex { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public string Author { get; set; }
public string Filename { get; set; }
}
public class VideoCategory
{
public Guid ID { get; set; }
public string Title { get; set; }
}
SimpleRepository repo = new SimpleRepository(SimpleRepositoryOptions.RunMigrations);
VideoCategory videoCategory = new VideoCategory();
videoCategory.ID = Guid.NewGuid();
videoCategory.Title = "TestTitle";
repo.Add<VideoCategory>(videoCategory);
Video video = new Video();
video.ID = Guid.NewGuid();
video.VideoCategory = videoCategory;
video.SortIndex = 1;
video.Title = "TestTitle";
video.Body = "TestBody";
video.Author = "TestAuthor";
video.Filename = "TestFile.flv";
repo.Add<Video>(video);
You're not missing anything. Simplerepository doesn't support one to many out of the box.
Heres a useful link that shows how to mangage foreign keys yourself in SimpleRepository -
subsonic-3-simplerepository
Have not tried it myself, but looks like it would actually work.
Fluent Nhibernate will do this foriegn key management for you automatically, but it's a LOT more complex.
PS If this was helpful, please vote it up.

Resources