Edit ObservableCollection field - windows-phone-7

I have ObservableCollection with 3 columns: id, name, image.
First two are filed with data from db and I want to fill the last one with my data. In image column I would like to put some static part + id
Is it possible?
I assume that some for loop will do the job, but don't know where to start
EDIT - MY CODE:
Object:
public class HabitatDB
{
public int id { get; set; }
public string name { get; set; }
public string imagelink { get; set; }
}
Getting data:
ObservableCollection<HabitatDB> _habitatEntries = null;
private void GetHabitats()
{
string strSelect = "SELECT id, name FROM habitat ORDER BY id ASC";
_habitatEntries = (Application.Current as App).db.SelectObservableCollection<HabitatDB>(strSelect);
HabitatListBox.ItemsSource = _habitatEntries;
}

I lost almost whole day and by accident I found REALLY simple solution...
Just a small change in class and you don't need to mess with ObservableCollection AT ALL.
public class HabitatDB
{
public int id { get; set; }
public string name { get; set; }
public string imagelink { get { return string.Format("graphics/habitats/{0}.png", id); } }
}
Then just <Image Source="{Binding imagelink}"/>

Related

EF Core non-existant column in query, how to rectify?

working my way through an EF core project I have inherited and am quite new when it comes to LINQ/EF core.
I'll cut this back to simplify things, and will demonstrate my problem with 4 basic tables.
Customer
CustomerId
Name
Contact
1
John
john#gmail.com
2
Peter
peter#gmail.com
CustomerTrade
Id
CustomerId
OtherDetail
T1
1
xyz
T2
1
abc
CustomerTradeParameter
ParamID
TradeId
Value
X
1
1234
Y
1
5678
CustomerTradeParameterType
ParamID
Name
OtherGenericInfo
X
Hello
Null
Y
Test
Null
Models
public class Customer : AuditableEntity
{
public long CustomerId { get; private set; }
public string Name { get; private set; }
public string Contact { get; private set; }
public virtual ICollection<CustomerTrade> CustomerTradeList{ get; set; }
protected Customer()
{ }
public class CustomerTrade : AuditableEntity
{
public long Id { get; private set; }
public long CustomerId { get; private set; }
public string OtherDetail { get; private set; }
public virtual ICollection<CustomerTradeParameter> CustomerTradeParameterList { get; set; } = new List<CustomerTradeParameter>();
protected CustomerTrade() // For EF Core
{ }
public class CustomerTradeParameter : AuditableEntity
{
public long TradeId { get; set; }
public string ParameterType { get; private set; }
public string Value{ get; private set; }
protected CustomerTradeParameter() // For EF Core
{ }
}
DTOs
public class CustomerTradeDto : AuditableDto
{
public long Id { get; set; }
public long CustomerId { get; set; }
public virtual ICollection<CustomerTradeParameterDto> CustomerTradeParameterList { get; set; } = new List<CustomerTradeParameterDto>();
}
public class CustomerTradeParameterDto : AuditableDto
{
public long TradeId { get; set; }
public string ParameterType { get; set; }
public string Value { get; set; }
}
The below query is attempting to retrieve a specific trade, and a list of its relevant parameters.
IQueryable<CustomerTradeDto> foundTrade = _database.CustomerTrade
.Select(trade => new CustomerTradeDto
{
Id = trade.Id,
CustomerId = trade.CustomerId,
CustomerTradeParameterList = trade.CustomerTradeParameterList.Select(param => new CustomerTradeParameterDto{
ParameterType = param.ParameterType,
TradeId = customerTrade.Id,
Value = param.Value
// (second question written further below) - If I wanted to additionally retrieve the CustomerTradeParameterType record
// (to get the name of this parameter), how would I embed this join?
// I originally had ParameterType defined as a "CustomerTradeParameterType" instead of a string,
// but am not sure how to add this extra join inside this select?
}).ToList()
})
.Where(e => e.Id == find.Id);
The .Select on CustomerTradeParameterList is raising the following error:
Microsoft.Data.SqlClient.SqlException (0x80131904): Invalid column name 'CustomerTradeId'.
I understand EF core is attempting to define a column that it is unsure of, but I am not sure how to fix this? The correct column is TradeId.
Secondly, I have an additional question regarding joins inside a sub .Select. In the query above I have a comment outlining the question.
Appreciate any tips you can provide!

Unable to get Item from SQLite.Net Async PCL

I am struggling to get an Item by ID using the asynchronous API of SQLite.Net Async PCL. Here is my model class
public class Invoice : IEntityBase
{
public Invoice()
{
LineItems = new List<LineItem>();
DateCreated = DateTime.Now;
}
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
public DateTime DateCreated { get; set; }
public int Term { get; set; }
public bool Paid { get; set; }
public decimal Total { get; set; }
public string Notes { get; set; }
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<LineItem> LineItems { get; set; }
}
And the LineItems that has a One to Many relationship here
[PrimaryKey, AutoIncrement, Column("_id")]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public string Category { get; set; }
public int Qty { get; set; }
[ForeignKey(typeof(Invoice))]
public int InvoiceId { get; set; }
[ManyToOne]
public Invoice Invoice { get; set; }
Here is the constructor:
public SQLiteAsyncConnection DbConnection;
public InvoiceDatabase(ISQLitePlatform platform, string databasePath)
{
if (DbConnection == null)
{
var connectionAsync = new Func<SQLiteConnectionWithLock>(() =>
new SQLiteConnectionWithLock
(
platform,
new SQLiteConnectionString(databasePath, false)
)
);
DbConnection = new SQLiteAsyncConnection(connectionAsync);
DbConnection.CreateTableAsync<Invoice>();
DbConnection.CreateTableAsync<LineItem>();
}
}
Other CRUD methods (Insert, GetALL) is working except getting an Invoice by ID, and both Visual Studio and Xamarin Studio are not giving me any useful stacktrace.
Here is the Get Method
private readonly InvoiceDatabase _database;
public InvoiceRepository(ISQLitePlatform platform, string databasePath)
{
if (_database == null)
{
_database = new InvoiceDatabase(platform, databasePath);
}
}
public async Task<Invoice> GetInvoice(int id)
{
var result = await _database.DbConnection.Table<Invoice>()
.Where(t => t.Id == id)
.FirstOrDefaultAsync();
return result;
}
I am passing in the Android implementation of SQLite, and like I said the Database is created but I am unable to get the Invoice object back, I even tried
public Task<Invoice> GetInvoiceWithChildren(int id)
{
return _database.DbConnection.GetWithChildrenAsync<Invoice>(id);
}
Any Help will be greatly appreciated.
After three days of chasing shadows it turned out that it is just a very simple thing that is tripping me up. I am tying to save a List of objects like so
[OneToMany(CascadeOperations = CascadeOperation.All)]
public List<LineItem> LineItems { get; set; }
I missed the part of the documentation that repeats the fact that SQLite.Net is a lightweight ORM - that point could not be stressed enough so you will have to remove your full size ORM hats such EF. So after reading from the SQLite-Net Extension documentation which says
Text blobbed properties
Text-blobbed properties are serialized into a text property when saved and deserialized when loaded. This allows storing simple objects in the same table in a single column.
Text-blobbed properties have a small overhead of serializing and deserializing the objects and some limitations, but are the best way to store simple objects like List or Dictionary of basic types or simple relationships.
I change my proptery like so and everything is now working as expected. Off now to dealing with the nuances of Async and Await
[TextBlob("LineItemBlobbed")]
public List<LineItem> LineItems { get; set; }
public string LineItemBlobbed { get; set; }

2 Models of same Properties, MVC3

Good Day guys!
I've just started using MVC3, I've 2 models in my application i.e. "Page" and "PageHistory" both has same properties. except that "PageHistory" has one extra property called "PageId" which references the "Page" model.
My question is am doing it in correct way? or should I use inheritance for this.
If inheritance is a option, How can I handle this, any examples will help me a lot.
My Model looks like as follows:
public class Page
{
private readonly IndianTime _g = new IndianTime();
public Page()
{
CreatedOn = _g.DateTime;
Properties = "Published";
Tags = "Page";
RelativeUrl = string.Empty;
}
public string Path
{
get { return (ParentPage != null) ? ParentPage.Heading + " >> " + Heading : Heading; }
}
[Key]
public int Id { get; set; }
[StringLength(200), Required, DataType(DataType.Text)]
public string Title { get; set; }
[StringLength(200), Required, DataType(DataType.Text)]
public string Heading { get; set; }
[MaxLength, Required, DataType(DataType.Html)]
public string Content { get; set; }
[Display(Name = "Reference Code"), ScaffoldColumn(false)]
public string ReferenceCode { get; set; }
[Required]
[Remote("CheckDuplicate", "Page", ErrorMessage = "Url has already taken", AdditionalFields = "initialUrl")]
public string Url { get; set; }
[Display(Name = "Created On"), ScaffoldColumn(false)]
public DateTime CreatedOn { get; set; }
//Parent Page Object (Self Reference: ParentId = > Id)
[Display(Name = "Parent Page")]
public int? ParentId { get; set; }
[DisplayFormat(NullDisplayText = "Root")]
public virtual Page ParentPage { get; set; }
public virtual ICollection<Page> ChildPages { get; set; }
}
I don't think inheritance will be the right way, the current structure looks ok to me.
See if you choose to make the Page as parent, and Pagehistory as being inherited from Page which actually it is not its just the pagehistory quite simply put.
Your idea of inheritance should always come from real world implementations, for ex. there could be diff. kinds of pages all inheriting from a Super Page type, while Page history is just a property to the page rather a complex property with properties inside it.

How to keep the value of the source when using InjectFrom

By injecting values ​​into my domain object, I would keep the values ​​of some properties.
Example:
Domain model
public class Person
{
public string Name { get; set; }
public Guid ID { get; set; }
public DateTime CreateAt { get; set; }
public string Notes { get; set; }
public IList<string> Tags { get; set; }
}
View Model
public class PersonViewMode
{
public string Name { get; set; }
public Guid ID { get; set; }
public DateTime CreateAt { get; set; }
public string Notes { get; set; }
public IList<string> Tags { get; set; }
public PersonViewMode() { ID = Guid.NewGuid(); } //You should use this value when it is the Target
}
Sample
var p = new Person
{
ID = Guid.NewGuid() //Should be ignored!
,
Name = "Riderman"
,
CreateAt = DateTime.Now
,
Notes = "teste de nota"
,
Tags = new[] {"Tag1", "Tag2", "Tag3"}
};
var pvm = new PersonViewMode();
pvm.InjectFrom(p); //Should use the ID value generated in the class constructor PersonViewMode
if you delete the set; from from the ViewModel's ID then it won't be set;
otherwise you could save the value of ID in a separate variable and put it back after injecting,
or you can create a custom valueinjection that would ignore "ID" or would receive a list of properties to ignore as a parameter
here's the example for a custom injection that receives a list of property names to ignore:
public class MyInj : ConventionInjection
{
private readonly string[] ignores = new string[] { };
public MyInj(params string[] ignores)
{
this.ignores = ignores;
}
protected override bool Match(ConventionInfo c)
{
if (ignores.Contains(c.SourceProp.Name)) return false;
return c.SourceProp.Name == c.TargetProp.Name && c.SourceProp.Type == c.TargetProp.Type;
}
}
and use it like this:
pvm.InjectFrom(new MyInj("ID"), p);
if you need to ignore more, you can do like this:
pvm.InjectFrom(new MyInj("ID","Prop2","Prop3"), p);

How to Count items in nested collection / codefirst EntityFramework

I've got CodeFirst collection defined as defined below.
For any given EmailOwnerId, I want to count the number of EmailDetailAttachments records exist without actually downloading all the images themselves.
I know I can do something like
var emailsToView = (from data in db.EmailDetails.Include("EmailDetailAttachments")
where data.EmailAccount.EmailOwnerId = 999
select data).ToList();
int cnt = 0;
foreach (var email in emailsToView)
{
cnt += email.EmailDetailAttachments.Count();
}
but that means I've already downloaded all the bytes of images from my far away server.
Any suggestion would be appreciated.
public class EmailDetail
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public int EmailOwnerId {get;set;}
public virtual ICollection<ImageDetail> EmailDetailAttachments { get; set; }
..
}
public class ImageDetail
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[MaxLengthAttribute(256)]
public string FileName { get; set; }
[MaxLengthAttribute(256)]
public string ContentMimeType { get; set; }
public byte[] ImageDataBytes { get; set; }
public DateTime ImageCreation { get; set; }
}
The engine should be able to update this to a COUNT(*) statement.
var emailsToView = (from data in db.EmailDetails // no Include
where data.EmailAccount.EmailOwnerId = 999
select new {
Detail = data,
Count=data.EmailDetailAttachments.Count() }
).ToList();
But you'll have to verify if this produces the right (and more efficient) SQL.

Resources