Override FluentNHibernate Auto mapping - fluent

I need change for the next class data type assumed by default FluentNHibernate Automapping
public class plaparte
{
public virtual int id { get; private set; }
public virtual int vivos { get; set; }
public virtual int lesionados { get; set; }
public virtual int quemados { get; set; }
public virtual int muertos { get; set; }
public virtual int otros { get; set; }
public virtual string colaboracion { get; set; }
public virtual decimal hectareas { get; set; }
public virtual string reconocimiento { get; set; }
public virtual string disposiciones { get; set; }
public virtual plaserv plaserv { get; set; }
}
}
I need for this class only the string type to be converted into TEXT in database
If I change by
public virtual string[] reconocimiento { get; set; }
FluentNHibernate takes a BLOB data type
I can do something like?
public class plaparteMappingOverride : IAutoMappingOverride<plaparte>
{
public void Override(AutoMapping<plaparte> mapping)
{
Map(x => x.disposiciones).CustomSqlTypeIs("TEXT");
}
}

To solve the problem I am using:
using System.ComponentModel.DataAnnotations;
...
public class plaparte
{
...
[StringLength(4000)]
public virtual string disposiciones { get; set; }
To create TEXT fields
[Update]
For work I need to create the next class
class StringLengthConvention : AttributePropertyConvention<StringLengthAttribute>
{
protected override void Apply(StringLengthAttribute attribute, IPropertyInstance instance)
{
instance.Length(attribute.MaximumLength);
}
}
is also necessary to add the convention Fluent automap
Like
static AutoPersistenceModel CreateAutomappings()
{
return AutoMap.AssemblyOf<plaparte>(new mapAutomapConfiguration())
.Conventions.Setup(c =>
{
c.Add<StringLengthConvention>();
});
}

Related

Trying to check a json file for the correct parameters using JsonConvert.DeserisalizeObject<t>

I'm using the ACE code editor to gather Json and send it to my application. Once the Json hits the application, I need to make sure there are certain key's inside the json so I am using JsonConvert.DeserisalizeObject<t> to do this. Here's how:
public void SubmitReport(string JsonStringSend)
{
try
{
ReportItem RptItem = JsonConvert.DeserializeObject<ReportItem>(JsonStringSend);
}
catch(err)
{
return View(err);
}
}
and:
public class ReportItem
{
public Guid ReportID;
public bool RequiresFilter;
public string MimeType { get; set; }
public string ExternalID { get; set; }
public DateTime CreatedBy { get; set; }
public string ExecutionScript { get; set; }
public string ExecutionParameter { get; set; }
public string ExecutionOrderBy { get; set; }
public List<DynamicFilter> DynamicFilters { get; set; }
public bool RequiresOrgID { get; set; }
public QueryFilter ReportFilter { get; set; }
public QueryRule ReportRules { get; set; }
public List<QueryColumn> Columns { get; set; }
}
But for some reason, it bounces right over the catch even when I make sure some of the key's are incorrect. Am I not understanding the correct usage JsonConvert.DeserisalizeObject<t>? Or, is there a better way to be doing this check?
By default, the deserializer "tries it's best" to deserialize the object. But JSon.NET supports validation, the "straightforward" way is probably JSon Schema: http://www.newtonsoft.com/jsonschema.
Simple case can be handled with JSon.NET directly:
public class ReportItem
{
[JsonProperty(Required = Required.Always)]
public bool RequiresFilter;
[JsonProperty(Required = Required.Always)]
public string MimeType { get; set; }
public DateTime CreatedBy { get; set; }
public string ExecutionScript { get; set; }
public string ExecutionParameter { get; set; }
public string ExecutionOrderBy { get; set; }
public bool RequiresOrgID { get; set; }
}

Breezejs entity save failing because json data is too large

Breeze seems to be creating a very large file considering the object model I am passing it to save.
I am only saving one instance of a drug with 1 Drug option with 1 available route and some text fields with a single word in each.
When I grab the bundle from debug.breeze.js from line 14705 and save it to a text file the file is 35+ mb. This seems like an aweful lot of data for this straight forward object model.
Is there any way to slim down the json with just the objects? So I don't have to alter the IIS settings?
****************** Link to exported json that breeze is sending to the server ***********
Sample of json that's causing the problem
****************Here is a screen shot of the graph *************
my datacontext.saveChanges code......
function saveDictionaryChanges(entity) {
var graph = manager.getEntityGraph(entity, 'drugIndications, ' +
'drugOptions, ' +
'drugOptions.concentrations, ' +
'drugOptions.availableRoutes, ' +
'drugOptions.availableDrugForms, ' +
'drugOptions.availableUnits');
// Filter for changes only
graph = graph.filter(function (entity) {
return entity.entityAspect.entityState.isAddedModifiedOrDeleted();
});
return manager.saveChanges(graph)
.then(saveSucceeded, saveFailed);
function saveSucceeded(result) {
//TODO: Commented out because WIP is on the back burner
//zStorage.save();
logSuccess('Saved Data', result, true);
}
function saveFailed(error) {
var msg = config.appErrorPrefix + 'Save failed: ' +
breeze.saveErrorMessageService.getErrorMessage(error);
error.message = msg;
logError(msg, error);
throw error;
}
}
my object model is
There are 4 other inherited available route types liquid,inhalation,injectable and topical. I only included AvailableSolidRoutes to help shorten he question.
public class AvailableRoute {
public int Id { get; set; }
public int DrugOptionId { get; set; }
public int RouteId { get; set; }
public virtual Route Route { get; set; }
}
public class AvailableSolidRoute : AvailableRoute {
public AvailableSolidRoute( ) { }
}
There is also a Inhalation,Injectable & topical concentration object that inherit from concentration. I've only include LiquidConcentration to help shorten the question.
public abstract class Concentration {
public int Id { get; set; }
public int DrugOptionId { get; set; }
public DrugOption DrugOption { get; set; }
public decimal Measure{ get; set; }
public int MassUnitId { get; set; }
public virtual Unit MassUnit { get; set; }
public int VolumeUnitId { get; set; }
public virtual Unit VolumeUnit { get; set; }
public int? DrugFormId { get; set; }
public virtual DrugForm DrugForm { get; set; }
public int DisplayOrder { get; set; }
}
public class LiquidConcentration : Concentration {
public LiquidConcentration( ) {}
}
There 4 other inherited types like solid option Liquid,Inhalation,Injectable & Topical
public class DrugOption {
public int Id { get; set; }
public int DrugId { get; set; }
public Drug Drug { get; set; }
public List<AvailableDrugForm> AvailableDrugForms { get; set; }
public List<AvailableRoute> AvailableRoutes{ get; set; }
public List<AvailableUnit> AvailableUnits { get; set; }
public List<Concentration> Concentrations { get; set; }
public string SpecialInstructions { get; set; }
}
public class SolidOption : DrugOption {
public SolidOption( ) { }
}
Drug is the root class that all the previous classes relate to:
public class Drug {
public int Id { get; set; }
public string Name { get; set; }
public string Alias{ get; set; }
public string Directions { get; set; }
public bool DirectionsIsEditable { get; set; }
public string SpecialDirections { get; set; }
public bool SpecialDirectionsIsEditable { get; set; }
public int? DisplayOrder { get; set; }
public IList<DrugIndication> DrugIndications { get; set; }
public IList<DrugOption> DrugOptions { get; set; }
public Drug( ) { }
}
***************** I fixed this issue (Was self induced hehe!) *************
So in order to make it easier to bind my "DrugOptions" to the UI. I created
clientside properties on the drug for each type of drug options.
I did not understand what this code was actually doing.. I added it thinking it would
remove the clientside property before sending entity changes to breeze. That is not it's purpose.
Rightly so breeze was confused about the clientside properties because it does not know about them.
if (changedProp === 'solidOption') {
delete changeArgs.entity.entityAspect.originalValues[changedProp];
}
I moved these properties to the Controller and it's perfectly fine now :)

Code first generating strange column

I have an MVC 4 application that is using code first to generate tables and columns in my SQL Server DB. I am trying to figure out how I ended up with an additional TABLE that was not intended. I have looked through some questions but not found the exact same problem I am having. I will try to explain this simply.
I have added a model called Associate which keeps track of associates that my client does business with. Each Associate needs a foriegn key of AssociateTypedID and RegionID.
namespace XXX.Models
{
public class Associate
{
public int AssociateId { get; set; }
public string AssociateName { get; set; }
public int AddressNumber { get; set; }
public string AddressStreet { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public string MainPhoneNumber { get; set; }
public string AssociateEmail { get; set; }
public string AssociateWebsite { get; set; }
public string ContactFirstName { get; set; }
public string ContactLastName { get; set; }
public string ContactPhoneNumber { get; set; }
public string ContactEmail { get; set; }
public int RegionId { get; set; }
public int AssociateTypeId { get; set; }
public virtual ICollection<AssociateType> AssociateTypes { get; set; }
public virtual ICollection<Region> Regions { get; set; }
}
}
AND
namespace XXX.Models
{
public class AssociateType
{
public int AssociateTypeId { get; set; }
public string AssociateTypeName { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
}
AND
namespace XXX.Models
{
public class Region
{
public int RegionId { get; set; }
public int RegionName { get; set; }
public int RegionDescription { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
}
AND
namespace XXX.Models
{
public class XXXDb : DbContext
{
public XXXDb(): base("name=DefaultConnection")
{
}
public DbSet<Associate> Associates { get; set; }
public DbSet<AssociateType> AssociateTypes { get; set; }
public DbSet<Region> Regions { get; set; }
}
}
So I have updated my code above and I'm getting very close to where I need to be in my database. I have the following tables generated.
Associates, AssociateTypes & Regions (each of them have the columns I would expect)
BUT I now have a new table called RegionAssociates which has the following columns:
Region_RegionId (int) & Associate_AssociateId (int)
This table was not expected or needed in my schema.
Your classes doesn't match your description of the model. You are saying
Each Associate can have a designation of AssociateType
I suppose that the same AssociateType can be assigned to more Associates, so there should be 1:N relationship between AssociateType and Associate.
But the Associate class defines the relationship the other way around - by convention public virtual ICollection<AssociateType> AssociateType { get; set; } creates 1:N relationship between Associate and AssociateType.
the correct definition of your classes would be
public class Associate
{
public int AssociateId { get; set; }
public string AssociateName { get; set; }
public int AddressNumber { get; set; }
public string AddressStreet { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zipcode { get; set; }
public string MainPhoneNumber { get; set; }
public string AssociateEmail { get; set; }
public string AssociateWebsite { get; set; }
public int RegionId { get; set; }
public int AssociateTypeId { get; set; }
public virtual AssociateType AssociateType { get; set; }
public string ContactFirstName { get; set; }
public string ContactLastName { get; set; }
public string ContactPhoneNumber { get; set; }
public string ContactEmail { get; set; }
public virtual ICollection<Region> Regions { get; set; }
}
public class AssociateType
{
public int AssociateTypeId { get; set; }
public string AssociateTypeName { get; set; }
public virtual ICollection<Associate> Associates { get; set; }
}
Can't say for sure what is missing from your configuration as you did't post it, but if you are using the fluent api something like this should fix the problem:
modelBuilder.Entity<AssociateType>()
.HasKey(t => t.AssociateTypeId);
modelBuilder.Entity<Associate>()
.HasRequired(t => t.AssociateType)
.WithRequiredPrincipal(t => t.Associate);
The above is adapted from this article http://msdn.microsoft.com/en-us/data/jj591620.aspx

EF Problems with Navigation Properties and Mapping

At start i wanted to mention that i've been fighting this thing for a few days and tried many of the answers more or less related to this problem. Yet I could not resolve it.
I have two classes that represent tables in a DB. These are the existing tables used by legacy application and I cannot change them.
Message can have multiple MessageRecipients.
Environment: MVC3, EF4.1
Classes are:
public class Message
{
[ForeignKey("MessageReciepients")]
public virtual int MessageID { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime Recieved { get; set; }
[ForeignKey("User")]
public int AuthorUserID { get; set; }
//P\\ Navigation properties
public virtual IList<MessageRecipient> MessageReciepients { get; set; }
public virtual User User { get; set; }
}
public class MessageRecipient
{
//[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int MessageID { get; set; }
public int UserID { get; set; }
public bool Read { get; set; }
public bool Important { get; set; }
public bool Deleted { get; set; }
public bool Destroyed { get; set; }
//P\\ Navigation Properties
public virtual User User { get; set; }
}
The error I have is:
The foreign key component 'MessageID' is not a declared property on
type 'MessageRecipient'. Verify that it has not been explicitly
excluded from the model and that it is a valid primitive property.
How to correctly map these classes, relationships to load the recipients of a message?
I can add that the navigation property User works correctly for a Message and loads a User's data correctly.
I'm not too experienced with .NET and I learn while doing this.
I tried some EF API config to map these i tried swearing at it, curse it, and been close to cry and pray at the same time. No Joy!!
I would really appreciate the help.
It turned out that the problem was with the composite key that i needed to use and it all could be solved with some attributes:
This is how it looks now:
public class Message
{
public int MessageID { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime Recieved { get; set; }
[ForeignKey("User")]
public int AuthorUserID { get; set; }
//P\\ Navigation properties
public virtual ICollection<MessageRecipient> MessageRecipients { get; set; }
public virtual User User { get; set; }
}
public class MessageRecipient
{
[Key, Column(Order=0), ForeignKey("User")]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int UserID { get; set; }
[Key, Column(Order = 1)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int MessageID { get; set; }
public bool Read { get; set; }
public bool Important { get; set; }
public bool Deleted { get; set; }
public bool Destroyed { get; set; }
//P\\ Navigation Properties
public virtual User User { get; set; }
}
fill in the missing properties:
public class Message
{
public int MessageID { get; set; }
}
public class MessageRecipient
{
public int MessageID { get; set; }
[ForeignKey("MessageID")]
public Message Message { get; set; }
}

Entity Framework 4.1 two FKs pointing to same table

I ran into an issue when adding two navigation properties of the same type in a model, giving me this error :
System.Data.SqlClient.SqlException:
Invalid column name : 'Createur_IdUtilisateur'.
Invalid column name : 'Proprietaire_IdUtilisateur'.
This is the code (broken) that I have :
public class Billet
{
[Key]
public int IdBillet { get; set; }
public int IdMandat { get; set; }
public string Titre { get; set; }
[AllowHtml]
public string Description { get; set; }
public int IdUtilisateurCreateur { get; set; }
public int IdUtilisateurProprietaire { get; set; }
public DateTime DateCreation { get; set; }
public DateTime? DateFermeture { get; set; }
public int EstimationTemps { get; set; }
public int Priorite { get; set; }
public bool FermetureParCreateur { get; set; }
public virtual ICollection<Intervention> Interventions { get; set; }
public virtual Mandat Mandat { get; set; }
public virtual Utilisateur Createur { get; set; }
public virtual Utilisateur Proprietaire { get; set; }
}
public class Utilisateur
{
[Key]
public int IdUtilisateur { get; set; }
public int IdUtilisateurRole { get; set; }
public string Courriel { get; set; }
public string Nom { get; set; }
public string Password { get; set; }
public bool Actif { get; set; }
public virtual UtilisateurRole Role { get; set; }
}
And this is what the relationships look like in the database.
I've read about [InverseProperty], but I'm not sure how I would go about implementing that in my situation. Do I need to add reverse navigation properties in my Utilisateur class to make this work?
Shortly after asking I realized my mistake, this is how I fixed it :
public class Entities : DbContext
{
...
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
...
modelBuilder.Entity<Billet>()
.HasRequired(b => b.Createur)
.WithMany()
.HasForeignKey(b => b.IdUtilisateurCreateur);
modelBuilder.Entity<Billet>()
.HasRequired(b => b.Proprietaire)
.WithMany()
.HasForeignKey(b => b.IdUtilisateurProprietaire);
}
}