public CaseMap()
{
Id(c => c.ID);//.GeneratedBy.Increment();
Map(c => c.CIN);
Map(c => c.CaseNumber);
Map(c => c.Name);
Map(c => c.RegistryNumber);
References(c => c.ApplicantType).Column("FK_ApplicantTypeId").Cascade.None();
References(c => c.ApplicationType).Column("FK_ApplicationTypeId").Cascade.None();
References(c => c.AVSUser).Column("FK_UserId").Cascade.None();
References(x => x.Program).Column("FK_ProgramId").Cascade.None();
References(c => c.CaseApplicant).Column("FK_CaseApplicantId").Cascade.SaveUpdate();
References(c => c.Address).Column("FK_AddressId").Cascade.SaveUpdate();
References(x => x.Spouse).Column("FK_SpouseId").Cascade.SaveUpdate();
Map(c => c.SpouseLink);
Map(c => c.Status);
Map(c => c.CreatedDate);
Map(c => c.UpdatedDate);
Map(c => c.IsArchived);
Table("tbl_Case");
}
Update method -
public bool Update(T persistableEntity)
{
if (persistableEntity != null)
{
session.BeginTransaction();
session.Update(persistableEntity);
session.Transaction.Commit();
return true;
}
return false;
}
The Update Call updates the Case table but adding new entry for child objects like CaseApplicant,Address and Spouse.
There was code error
Instead of
cCase.Address = new CaseAddress();
cCase.Address.Street = record.ResidenceStreet;
It should have been just
cCase.Address.Street = record.ResidenceStreet;
cCase.Address = new CaseAddress() was creating a new object for CaseAddress result in new entry.
Also the update method should be session.Merge instead of update
public bool Update(T persistableEntity)
{
if (persistableEntity != null)
{
session.BeginTransaction();
session.Merge(persistableEntity);
session.Transaction.Commit();
return true;
}
return false;
}
Related
I want the null value during mapping DTO to DBO model to be ignored. This is the code:
DTO / DBO models have both property named items:
public virtual ICollection<price_list_item> items { get; set; }
DBO constructor:
public price_list()
{
this.items = new List<price_list_item>();
}
DTO constructor has no propert initialization
public price_list()
{
}
AutoMapper Profile:
this.CreateMap<DTO.price_list, DBO.price_list>()
.ForMember(m => m.id, src => src.Ignore())
.ForMember(m => m.currency_id, src => src.MapFrom(f => f.currency))
.ForMember(dest => dest.items, opt => opt.Condition(src => (src.items != null)))
API Controller:
[HttpPut]
[Route("{id:long}")]
public async Task<DTO.price_list> UpdateOneAsync(long id, [FromBody]DTO.price_list payload)
{
if (payload == null)
{
throw new ArgumentNullException("payload");
}
Console.WriteLine(payload.items == null);
var _entity = await this.IDataRepository.price_lists
.Where(w => w.id == id)
.Include(i => i.items)
.FirstOrDefaultAsync();
if (_entity == null)
{
NotFound();
return null;
}
Console.WriteLine(_entity.items.Count);
// map fields to existing model
this.IMapper.Map<DTO.price_list, DBO.price_list>(payload, _entity);
Console.WriteLine(_entity.items.Count);
When I send to API a JSON without any sign of 'items' property, Console output is:
True
1200 // price list in dbo has 1200 items
0 // here I need to have still 1200 items
What am I doing wrong? Why the condition is not respected and items property is not 'skiped' ?
Thanks
Lucian thanks, PreCondition solved the problem. This is working code:
this.CreateMap<DTO.price_list, DBO.price_list>()
.ForMember(m => m.id, src => src.Ignore())
.ForMember(m => m.currency_id, src => src.MapFrom(f => f.currency))
.ForMember(dest => dest.items, opt => opt.PreCondition(src => (src.items != null)))
I have this code generating a "Calculated" or "Output" property every time another property changes. The derived property is generated correctly, but since CreateBlurImage is a bit long-running, the UI gets frozen as it runs.
What would be the correct way to get the same end result, but asynchronously?
EDIT this is the current version of my code after some suggestions from #Shane, but still with an UI that keeps frozen until all the processing completes. Notice that there are quite a handful of cascading updates, if that matters:
public ColetaIsis Model { get; private set; }
public string NomePaciente { get { return Model?.NomePaciente; } }
public DateTime DataRealização { get { return Model.DataRealização; } }
public BitmapSource Listras
{
get { return _listras; }
set { this.RaiseAndSetIfChanged(ref _listras, value); }
}
BitmapSource _listras;
public double[,] Grayscale { get { return _grayscale.Value; } }
readonly ObservableAsPropertyHelper<double[,]> _grayscale;
public double[,] BlurMenor { get { return _blurMenor.Value; } }
readonly ObservableAsPropertyHelper<double[,]> _blurMenor;
public double[,] BlurMaior { get { return _blurMaior.Value; } }
readonly ObservableAsPropertyHelper<double[,]> _blurMaior;
public double[,] Diferença { get { return _diferença.Value; } }
readonly ObservableAsPropertyHelper<double[,]> _diferença;
public BitmapSource FiltradaMenor { get { return _filtradaMenor?.Value; } }
readonly ObservableAsPropertyHelper<BitmapSource> _filtradaMenor;
public BitmapSource FiltradaMaior { get { return _filtradaMaior?.Value; } }
readonly ObservableAsPropertyHelper<BitmapSource> _filtradaMaior;
public BitmapSource ImagemDiferença { get { return _imagemDiferença?.Value; } }
readonly ObservableAsPropertyHelper<BitmapSource> _imagemDiferença;
public IEnumerable<ScatterPoint> Picos => _picos;
IEnumerable<ScatterPoint> _picos;
// CONSTRUTOR
public ColetaIsisViewModel(ColetaIsis model)
{
this.WhenAnyValue(x => x.Listras)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(im => GetArray.FromChannels(im, 0, 1))
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Grayscale, out _grayscale, scheduler:RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.Grayscale)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(ar => Gaussian.GaussianConvolution(ar, 1.5))
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.BlurMenor, out _blurMenor, scheduler: RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.BlurMenor)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(ar => Gaussian.VerticalGaussianConvolution(ar, 5))
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.BlurMaior, out _blurMaior, scheduler: RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.BlurMenor, x => x.BlurMaior)
.Where(tuple => tuple.Item1 != null && tuple.Item2 != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(tuple => ArrayOperations.Diferença(tuple.Item1, tuple.Item2))
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Diferença, out _diferença, scheduler: RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.BlurMenor)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.FiltradaMenor, out _filtradaMenor, scheduler: RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.BlurMaior)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.FiltradaMaior, out _filtradaMaior, scheduler: RxApp.MainThreadScheduler);
this.WhenAnyValue(x => x.Diferença)
.Where(item => item != null)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(ar => { ConversorImagem.Converter(ar, out BitmapSource im); return im; })
//.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.ImagemDiferença, out _imagemDiferença, scheduler: RxApp.MainThreadScheduler);
Model = model;
Listras = Model.Listras; // fires up the initial cascading updates
}
Would any of these ways work? This way the CreateBlurImage part is done off the UIThread
public MyClass()
{
this.WhenAnyValue(x => x.StripedImage)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(im => CreateBlurImage(im))
.ObserveOn(RxApp.MainThreadScheduler)
.ToProperty(this, x => x.Filtered, out _filtered);
}
or I'm pretty sure specifying the scheduler on ToProperty will be the same as above
public MyClass()
{
this.WhenAnyValue(x => x.StripedImage)
.ObserveOn(RxApp.TaskpoolScheduler)
.Select(im => CreateBlurImage(im))
.ToProperty(this, x => x.Filtered, out _filtered, scheduler:RxApp.MainThreadScheduler);
}
In my data model, I have a base class Case for which there can be a few different types: an Investigation, DisciplinaryAction, etc. These all inherit from Case. This is how I've modeled it in Entity Framework.
public abstract class Case : BaseEntity
{
public int CaseId { get; set; }
public int PlanId { get; set; }
public int CaseTypeId { get; set; }
public CaseType CaseType { get; set; }
}
public class Investigation : Case
{
}
For the inherited classes, CaseId is the primary key and foreign key. I have a single DbSet for Cases. When I need to explicitly access one of the inherited types, I use context.Cases.OfType<Investigation>(). All this is working fine.
In my CaseRepository, I have a method to get a case by ID:
public Case GetById(int id)
{
var oversightCase = context.Cases
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.FirstOrDefault(f => f.CaseId == id);
}
My question is that, for one of the inherited types, I want to include another navigation property. Is there a way to access inherited types generically and include properties that not all inherited types have in a manner that's less disgusting than this:
public Case GetById(int id)
{
var oversightCase = context.Cases
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects)
.FirstOrDefault(f => f.CaseId == id);
if (oversightCase != null && oversightCase is Investigation)
{
oversightCase = context.Cases.OfType<Investigation>()
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects)
.Include(p => p.Investigatee)
.FirstOrDefault(f => f.CaseId == id);
}
return oversightCase;
}
Yes, you will need to do two requests when the case id is related to Investigation. Doing it like you write it, is not the correct way.
Because if the id is related to an Investigation you are doing two big requests to your database with each one doing the same first four join queries.
The second request (in your if statement block) is just an extension of your first request because they share this code:
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects)
To avoid performance issue in the future:
First create a generic method like the code below where T must be a subclass of Case:
public IQueryable<T> GetCaseCommonData<T>()
where T : Case
{
return context.Cases.OfType<T>
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects);
}
Second, use the generic method like this:
public Case GetById(int id)
{
Case oversightCase;
if (context.Cases.OfType<Investigation>().Any(f => f.CaseId == id))
{
oversightCase = GetCaseCommonData<Investigation>()
.Include(p => p.Investigatee)
.SingleOrDefault(f => f.CaseId == id);
}
else
{
oversightCase = GetCaseCommonData<Case>()
.SingleOrDefault(f => f.CaseId == id);
}
return oversightCase;
}
With my solution, the include like the ocde below are executed once:
.Include(p => p.Owner)
.Include(p => p.CreatedBy)
.Include(p => p.ModifiedBy)
.Include(p => p.LinkedObjects);
By refactoring your code like I do, the query to check if a case id is an Investigation type is more efficient than the code you write for the same purpose:
context.Cases.OfType<Investigation>().Any(f => f.CaseId == id)
I am getting this error while creating SessionFactory. Here is the code, if some can check this out.
class NHibernateHelper {
private static ISessionFactory _sessionFactory;
private static ISessionFactory SessionFactory {
get {
if (_sessionFactory == null) {
InitializeSessionFactory();
}
return _sessionFactory;
}
}
private static void InitializeSessionFactory() {
_sessionFactory = Fluently.Configure().
Database(MsSqlConfiguration.MsSql2008.ConnectionString
("Server=tcp:z4m56fgh.database.windows.net,1433;Database=db;User ID=user;Password=xxxxx;Trusted_Connection=False;Encrypt=True;Connection Timeout=30;").
ShowSql()).
Mappings(m => m.FluentMappings.AddFromAssemblyOf<House>()).
ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true)).
BuildSessionFactory();
}
public static ISession OpenSession() {
return SessionFactory.OpenSession();
}
}
Mappings:
public class HouseMap : ClassMap<House> {
public HouseMap() {
Id(x => x.Id);
References(x => x.Owner).Cascade.All();
References(x => x.Rooms).Cascade.All();
References(x => x.Consumptions).Cascade.All();
}
}
public class ConsumptionMap : ClassMap<Consumption> {
public ConsumptionMap() {
Id(x => x.Id);
Map(x => x.Type);
Map(x => x.AvgDay);
Map(x => x.AvgMonth);
Map(x => x.AvgYear);
}
}
public class RoomMap : ClassMap<Room> {
public RoomMap() {
Id(x => x.Id);
Map(x => x.Name);
Map(x => x.Number);
Component<TemperatureData>(x => x.TemperatureData,
t => {
t.Map(x => x.TemperatureCurrent, "Current");
t.Map(x => x.TemperatureSet, "Set");
});
Component<RoomFeatures>(x => x.Features,
f => {
f.Map(x => x.Shutters, "ShuttersUp");
f.Map(x => x.Lights, "LightsOn");
});
}
}
This exact class NHibernateHelper works with another Model, so it must be something wrong with my mappings. Also, it still does not work if i exclude everything from HouseMap, i.e. comment on the References.
It is being a little difficult to realize what is the source of your problem without the classes, although, a guess would be at the Consumptions property. If it is a list (as it seems by its name) it should be mapped with HasMany instead of References.
Besides, maybe you could attach the stack trace with the InnerException. This could give us a clue.
I have many blocks of code that look like the following:
modelBuilder
.Entity<Foo>()
.Property(t => t.X)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 1) { IsUnique = true }));
modelBuilder
.Entity<Foo>()
.Property(t => t.Y)
.IsRequired()
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_X_Y", 2) { IsUnique = true }));
This block is telling EF, through fluent API, to create a unique index with columns X and Y together, on table Foo.
Another block of code just like that would be this, with columns R and S on table Bar:
modelBuilder
.Entity<Bar>()
.Property(t => t.R)
.IsRequired()
.HasMaxLength(60)
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_R_S", 1) { IsUnique = true }));
modelBuilder
.Entity<Bar>()
.Property(t => t.S)
.IsRequired()
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute("IX_R_S", 2) { IsUnique = true }));
I want to refactor this, so that it ends up looking something like:
CreateCompositeUnique<Foo>(modelBuilder, "IX_X_Y", t => new {t.X, t.Y});
CreateCompositeUnique<Bar>(modelBuilder, "IX_R_S", t => new {t.R, t.S});
I was thinking of something like this:
private void CreateCompositeUnique<T>(DbModelBuilder modelBuilder, string indexName, List<Expression<Func<T, byte[]>>> properties)
{
for (int i = 0; i < properties.Count; i++)
{
modelBuilder
.Entity<typeof(T)>()
.Property(properties[i])
.IsRequired()
.HasMaxLength(60) // --only when propery is string
.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation(new IndexAttribute(indexName, i) { IsUnique = true }));
}
}
But I have some questions:
Is this a good idea?
How do I know if the property is string?
What is the best way to pass the parameters?
How do I access "T"? I'm getting a compile error at .Entity<typeof(T)>
Following Gert Arnold's advice, I created a extension method. Actually they are two extension methods (why? autoexplicative, see code comments)
public static class ExtensionMethods
{
public static StringPropertyConfiguration HasIndex(this StringPropertyConfiguration config, string indexName, int i)
{
return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation((new IndexAttribute(indexName, i) { IsUnique = true })));
}
public static PrimitivePropertyConfiguration HasIndex(this PrimitivePropertyConfiguration config, string indexName, int i)
{
return config.HasColumnAnnotation(IndexAnnotation.AnnotationName, new IndexAnnotation((new IndexAttribute(indexName, i) { IsUnique = true })));
}
}
And usage is like this:
modelBuilder
.Entity<Foo>()
.Property(t => t.X)
.IsRequired()
.HasMaxLength(60)
.HasIndex("IX_X_Y", 1); // <-- here (X is string)
modelBuilder
.Entity<Foo>()
.Property(t => t.Y)
.IsRequired()
.HasIndex("IX_X_Y", 2); // <-- and here (Y is a primitive)