With SQLite-Net Extensions, is there a way to have List<string>? - sqlite-net-extensions

In the documentation for SQLite-Net Extensions, it shows having an object (Stock) with property that has a List of another object (Valuation) with a OneToMany relationship. I am able to reproduce that fine.
What I want to do is to be able to add a property to Stock that is a List of strings.
But when I try to add a List<string> property, if I have no attributes on it, I get the error: 'Don't know about System.Collections.Generic.List`1[System.String]'
If I add the [OneToMany] attribute to the property, I get the error: 'OneToMany relationships require Primary Key in the destination entity'
Is there any way that SQLite-Net Extensions can handle List<string> instead of List of non primative types?

Any kind of relationship requires a destination table. In your case, a string is not stored as a table. You can either convert that value into a complex object that is stored in a separate table and use either a OneToMany or a ManyToMany or serialize the list as a string and save it in a different field.
For the latter case SQLite-Net Extensions includes a TextBlob attribute that does exactly that. It serializes the property as a string before storing the objech to database and deserializes it after reading from database.
public class Person
{
public string Name { get; set; }
[TextBlob("PhonesBlobbed")]
public List<string> PhoneNumbers { get; set; }
[TextBlob("AddressesBlobbed")]
public List<Address> Addresses { get; set; }
public string PhonesBlobbed { get; set; } // serialized phone numbers
public string AddressesBlobbed { get; set; } // serialized addresses
}
More info in the manual.

Related

WhiteList subclass via Bind

Is there a way to white list a subclass via the attribute?
public class VoteQuestionViewModel
{
[Display(Name = "Vote Question")]
public string Name { get; set; }
public VoteTypeViewModel VoteType { get; set; }
}
public class VoteTypeViewModel
{
public int Id { get; set; }
[Display(Name = "Type of Question")]
public string Type { get; set; }
[Display(Name = "Description")]
public string Description { get; set; }
}
The below will will only work to white list class property, but it will not work to whitelist child class property:
public async Task<IActionResult> Create([Bind("Name, VoteType.Description")] VoteQuestionViewModel voteQuestion)
The method you included in your question is the only way. Bind works on posted values. In other words, it's looking at the key names in the form data. In that respect, there is no VoteType key and never will be: only the properties on that class that were posted, i.e. VoteType.Description.
That said, not only is it extremely bad practice to use Bind at all, but using it in conjunction with view models makes absolutely no sense. The whole point of Bind is to allow you to include/exclude a subset of properties on an entity class. Likewise, the whole purpose of a view model is to deal with only the data that the view needs to work with. Therefore, if you don't want a property to be included in the post, don't put it on the view model. Even then, view models come with the extra caveat that data has to be mapped to/from the entity class onto to them. That gives you the ability to explicitly decide what will and will not get mapped. For example, if you need Id for some reason in your view, but you don't want the user to be able to change it, simply don't map it from your view model back onto your entity.

mvc 5: Optional model property

I have a model called Project
public class Project
{
[Key]
public int ID { set; get; }
public string Title { set; get; }
public string Image { set; get; }
public double? gained { set; get; }
}
I use this model with two stored procedures one returns all the properties and the other without the property gained. And I got this error
The data reader is incompatible with the specified 'Test.Models.Project'. A member of the type, 'Gained', does not have a corresponding column in the data reader with the same name.
I don't want to write separate models for each stored procedure.
How to solve that please ?
The datareader is kind of dumb in the sense that it will only match what was sent back to it. If a column is missing, it fails, as you can see.
The easiest way to solve this would be to update your second SELECT statement in your stored procedure to pass back a column named gained.
SELECT ID, Title, Image, NULL as gained FROM table
Here, we are passing back no data (NULL) as the gained column. This should make the data reader happy, keep you from needing multiple models and not send back any extra data.
The other possibility would be to use inheritance in your models. Have a base model that does not include gained, and have a second model that inherits from the base model that does include gained.
public class ProjectBase
{
[Key]
public int ID { set; get; }
public string Title { set; get; }
public string Image { set; get; }
}
public class ProjectGained : ProjectBase{
public double? gained { set; get; }
}

Unable to serialize object using Javasciptserializer

I'm trying to serialize an object to JSON string as shown below:
new JavaScriptSerializer().Serialize(person)
Here, person is the object which is having lot of attributes such as name, address, city, state, etc but I have decorated the class as shown below so that it'll serialize only name and address.
using System;
using System.Runtime.Serialization;
namespace DataAccess.Models
{
[Serializable]
[DataContract]
public class Person
{
public string Id { get; set; }
[DataMember(Name = "full-name")]
public string Name { get; set; }
[DataMember(Name = "address")]
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
}
But when I run the program, the new JavaScriptSerializer().Serialize(person) gives me JSON with all the data including Id, City, State, Zip.
Why is it not giving me only full-name & address? It seems like it is completely ignoring these DataMember attributes.
When I use JsonConvert.SerializeObject(person) from Newtonsoft, everything works perfect & it serializes only Name & Address but JavascriptSerializer is giving all data.
Can any one tell me what could be the issue?
Consider using the [ScriptIgnore()] Attribute on those properties you don't want to be serialized.
http://msdn.microsoft.com/en-us/library/system.web.script.serialization.scriptignoreattribute(v=vs.100).aspx
See here for a detailed list of how the JavaScriptSerializer will handle different types: http://msdn.microsoft.com/en-us/library/system.web.script.serialization.javascriptserializer(v=vs.110).aspx
Edit:
Note that the JavascriptSerializer is not aware of the DataMember attributes and they therefore will not be used by the JavascriptSerializer (JSON.net will use them, but JSON.Net also defines it's own constructs for this: [JsonIgnore()] [JsonObject] and many other attributes support custom-naming). To accomplish this, try using the DataContractJsonSerializer in the System.Runtime.Serialization.Json namespace with some draw-backs.
See this question and answer for additional information:
JavaScriptSerializer.Deserialize - how to change field names

MVC CodeFirst one to many relationship creates new data

I'm using CodeFirst with MVC 3 and have these two classes:
public class Person
{
public int PersonId { get; set; }
[Email]
[Required]
public string Email { get; set; }
public string Passwort { get; set; }
public virtual City City { get; set; }
}
public class City
{
public int CityId { get; set; }
[Required]
public string Name { get; set; }
public virtual IEnumerable<Person> Persons { get; set; }
}
When adding a new person I want to reference a city to this person. Therefore i'm using a SelectList with all cities in my view. The CityId and the object is transferred correctly to the Post-method, but when saving the changes to the database I will have a new object in the city-table (with same name, but new Id).
I suggest there's something wrong with the relations in my models. Maybe somebody can help me.
If you give your Person model an explicit CityId property, then you won't need to retrieve the City object from your repository, you can just assign the CityId value directly to the Person object and save it. For really straightforward views, you don't need to use a viewmodel either, you could receive a Person instance into the POST action method and CityId would already be assigned, assuming the html field in the View has the same name.
This should fix your problem, because you will then know you are explicitly using a CityId that already exists.
Your database will already contain a Person.City_CityId field anyway so you're not creating anything new, just giving yourself more control over the situation. Sometimes you may need to use a [ForeignKey] attribute in the model to connect the Person.CityId property with the virtual property, but using the standard naming convention this shouldn't be necessary.

Representing IList<Guid> property in Entity Framework 4.0

We have a model class defined that I want to produce from our EF 4.0 edmx for persistence. The class looks roughly as follows:
[DataContract]
public class Schedule
{
[DataMember]
public string Name { get; set; }
[DataMember]
public Guid Id { get; set; }
[DataMember]
public DateTime RunDate { get; set; }
[DataMember]
public IList<Guid> Routes { get; set; }
[DataMember]
public IList<Guid> Paths { get; set; }
}
How do I represent Routes and Paths on the edmx design surface? I can't see anyway of doing this other than creating two entities with a single Guid Id field then setting a 1-* Association to Schedule. I'd rather not have to do that as we'll then have a Route and Path class that isn't what we want at the moment.
We haven't had chance to look at Code First yet and don't really have time to figure it out for this project but would it support our needs?
Thanks for any assistance.
You must either use related entities or you musn't map them directly. You can for example map another fields called RoutesSerialized and PathsSerialized which will be of type string and contains all Guids stored as strings and separated by semicolon. Your current properties will use return IEnumerable and use internally use functions like String.Join, String.Split, ToString and Guid.Parse.

Resources