what is the procedure for creating database in windows phone 8? - windows-phone-8

I am developing an application in widows phone 8,in my application I have to create a database .how can I do this ,I am new to this.please help me out

Well, that depends on what backend you want, if you are going to store small amounts of data I would recommend that you create an xml file in local storage. If you are looking at something more complex, you can use Linq-to-SQL with SQL Server CE.
The code to generate such a database involves creating a DataContext class similar to this:
public class MyDbContext : DataContext
{
public const string MyDbConnString = "isostore:/MyDb.sdf";
public MyDbContext(string pConnString = MyDbConnString) : base(pConnString) { }
public Table<SomeClass1> table1;
public Table<SomeClass2> table2;
}
Then you would create the classes that will function as "tables" like this:
[Table(Name = "MyTable")]
public class SomeClass1
{
[Column(IsPrimaryKey = true, Name = "ID")]
public int Id { get; set; }
[Column(Name = "Name")]
public string Name { get; set; }
}
Lastly in the App.xaml.cs you would place code to create the database in the constructor:
public App()
{
// ... other code
CreateDatabase();
}
private void CreateDatabase()
{
using (var context = new MyDbContext())
{
if (!context.DatabaseExists())
{
context.CreateDatabase();
}
}
}
Note that if you want an in depth explanation of how the classes need to be set up, if you want to create foreign key references for example, you need to look at the MS documentation.
I would recommend starting here.

Related

MySQL and EF Core 6 error The LINQ expression could not be translated

I recently updated our project from EF Core 2.2.6 to 6.x (along with and upgrade from .NET core 3.1 to .NET 6) and now I'm get errors like the one stated in the title whenever the query gets even a little complicated. One of those cases is when you add a GroupBy clause. Below is an example of a failing query.
_context.MyTable
.Where(a => a.Name.Contains("service"))
.GroupBy(ss => ss.IsServiceSpecific)
The entire error is:
The LINQ expression 'DbSet< MyTable >()
.Where(a => a.Name.Contains("service"))
.GroupBy(ss => ss.IsServiceSpecific)' could not be translated. Either rewrite the query in a form that can be translated, or switch
to client evaluation explicitly by inserting a call to 'AsEnumerable',
'AsAsyncEnumerable', 'ToList', or 'ToListAsync'
The setup at this MySQL::Entity Framework Core Support URL is exactly what I did (there are only two steps to set it up). My DI config looks like this:
builder.Services.AddEntityFrameworkMySQL()
.AddDbContext<MydbContext>(options =>
{
options.UseMySQL(builder.Configuration.GetConnectionString("DefaultConnection"));
});
It will execute simple queries but more complex ones always generate this error. It says to rewrite the query and force client side evaluation by using AsEnumerable or ToList but I don't want to drag all that data to the client and I expect that a simple group by can be translated and handled server side.
I did find one article that talks about this problem but I'm not getting if it's suggesting an actual solution.
This shouldn't be this hard and I feel like I'm missing something simple.
Model
internal class Post
{
public int PostId { get; set; }
public string? Title { get; set; }
public string? Content { get; set; }
public int BlogId { get; set; }
}
DBContext
internal class BloggingContext : DbContext
{
public DbSet<Post>? Posts { get; set; }
public string DbPath { get; }
public BloggingContext()
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
DbPath = $"{path}{Path.DirectorySeparatorChar}blogging.db";
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
=> options.UseSqlite($"Data Source={DbPath}");
}
Main
internal class Program
{
static void Main(string[] args)
{
using (var db = new BloggingContext())
{
var posts = db.Posts.Where(s => s.Title.Contains("Hello")).GroupBy(g => g.BlogId == 1994).Select(s => new { Key = s.Key, Counts = s.Count() }).ToList();
foreach (var p in posts)
{
Console.WriteLine(p);
}
}
}
}
Conclusion: You might add Select statement after GroupBy.

Retrieving data from the same database with the Identity

I connected the identity model of my WebApp to my MySQL Database, and modified it like I want to connect.
My question is the next: If I want to get data from tables not used in the Identity but still from the same database, What is the correct way to do it? Should I open a new connection and get the data with a class? Is there a way to implement it in the model?
I attach the code to connect to the database:
public void Configuration(IAppBuilder app)
{
DbConfiguration.SetConfiguration(new MySqlEFConfiguration());
ConfigureAuth(app);
context = new ApplicationDbContext();
}
And my connectionStrings:
<connectionStrings>
<add name="DefaultConnection" connectionString="server=x.x.x.x;uid=user;password=pwd;database=db;port=3306;charset=utf8" providerName="MySql.Data.MySqlClient" />
</connectionStrings>
(Sorry if the question is too obvious, I'm starting to develop apps in ASP.NET MVC)
Yes, all you need to do is open the connection when it is required.
So, i assume you did something like this with your MySQL Database connections
public class MySqlInitializer : IDatabaseInitializer<ApplicationDbContext>
{
public void InitializeDatabase(ApplicationDbContext context)
{
if (!context.Database.Exists())
{
// if database did not exist before - create it
context.Database.Create();
}
else
{
// query to check if MigrationHistory table is present in the database
var migrationHistoryTableExists = ((IObjectContextAdapter)context).ObjectContext.ExecuteStoreQuery<int>(
string.Format("SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{0}' AND table_name = '__MigrationHistory'",
"[Insert your database schema here - such as 'users']"));
// if MigrationHistory table is not there (which is the case first time we run) - create it
if (migrationHistoryTableExists.FirstOrDefault() == 0)
{
context.Database.Delete();
context.Database.Create();
}
}
}}
and your ApplicationDbContext class will be like this
public class ApplicationUser : IdentityUser{}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
static ApplicationDbContext()
{
Database.SetInitializer(new MySqlInitializer());
}
public ApplicationDbContext()
: base("DefaultConnection")
{
}
}
Now, to do some queries from database, you need to create an object of ApplicationDbContext
So, your Next Question "Is there a way to implement it in the model?" Yes there is you need to Create a View Model.
public class ItemProduct
{
public int Id {get; set;};
public string Name {get; set;};
}
So, lets say a Product Table exists in your database and we can query on it.
public class HomeController : Controller
{
ApplicationDbContext context = new ApplicationDbContext();
public ActionResult AnyName()
{
List<ItemProduct> lstProducts = new List<ItemProduct>();
var getProducts = (from p in context.Products
select p).ToList();
foreach(var item in getProducts)
{
ItemProduct pro = new ItemProduct()
{
pro.Id = item.Id,
pro.Name = item.Name
};
lstProducts.Add(pro);
}
// So, you have all your Products in ItemProduct Class list.
// Now, return lstProducts to your View to show it on front end
}
}
Hope this answer your question :)

how to maintian the EF connection string at one place?

I have the following in my project solution,am trying to maintain the Database connection of Entity framework at one place so that if I have to switch the database to a different vendor(like MYSQL to MSSQL or vice-versa) I can just change the connection name at one place and doesn't have to change at all the places...I tried the following structure but running into an error,how to fix it?
Project#1
Dashboard.EntityFramework
-->bitDbConnection.cs
using
namespace Dashboard.EntityFramework
{
public class bitDbConnection
{
BitDatabaseEntities bitDB = new BitDatabaseEntities();
}
}
Project#2
Dashboard.Repository
-->Repository.cs
using Dashboard.EntityFramework
when I try use to bitDB variable I can the below error
Error:-
The name bitDB does not exist in current context
This probably isn't what you want but to get your code to work, write it like this:
namespace Dashboard.EntityFramework
{
public class bitDbConnection
{
public BitDatabaseEntities bitDB = new BitDatabaseEntities();
}
}
using Dashboard.EntityFramework
public class Repository
{
public void DoSomething()
{
var bitDB = new bitDbConnection().bitDB;
}
}
So, first make bitDB field public, and then use it...
edit for question in comments:
public class Repository
{
private BitDatabaseEntities bitDB = new BitDatabaseEntities().bitDB;
public void DoSomething()
{
var x = bitDB.ToString();
}
}

Generic Singleton and share data between pages

To share data (complexe data ) between pages in my windows phone 8 application I want to implement a singleton, but I want it to be generic, is it possible? I suppose that it creates a new instance for each type isn't it?
public sealed class NavigationContextService<T>
{
private static readonly NavigationContextService<T> instance = new NavigationContextService<T>();
private NavigationContextService()
{
}
public static NavigationContextService<T> Instance
{
get
{
return instance;
}
}
public List<T> ShareList { get; set; }
public T ShareData { get; set; }
}
It is creating a new instance for every type, because it is generic - you want it to be like this (if you start with generics, take a look at some tutorials, blogs or MSDN - you will easily find many in the internet).
It is still a singleton. When you use
NavigationContextService<string>.Instance.ShareList.Add("Text");
then you have one Instance for type string. Generics helps a lot when you want to create same methods/classes that differ in type.
On the other hand if you want to create Singleton that will hold different types then you can for example modify your class to be non Generic like this:
public sealed class NavigationContextServiceNonGeneric
{
private static readonly NavigationContextServiceNonGeneric instance = new NavigationContextServiceNonGeneric();
private NavigationContextServiceNonGeneric() { ShareList = new List<object>(); }
public static NavigationContextServiceNonGeneric Instance
{ get { return instance; } }
public List<object> ShareList { get; set; }
public object ShareData { get; set; }
}
As you can see in the code above I haven't defined the 'exact' type of shared data - it is object type. Then you can easily hold most of data with it:
NavigationContextServiceNonGeneric.Instance.ShareList.Add("Text");
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3);
NavigationContextServiceNonGeneric.Instance.ShareList.Add(3.0f);
It is singleton, which can hold different types of shared data. BUT it has also disavantages - the main is that you have to remember what type of data you hold and in what order. In my opinion Generic version is better because of that fact.
Everything depends on the purpose of your code. There may be easier and better ways that those two approaches.
As for the Page Navigation, you can for example try to use a method from this article - you extend Navigation service to pass the object:
public static class Extensions
{
private static object Data;
public static void Navigate(this NavigationService navigationService, Uri source, object data)
{
Data = data;
navigationService.Navigate(source);
}
public static object GetNavigationData(this NavigationService service) { return Data; }
}
Then you use it:
NavigationService.Navigate(yourUri, DataToPass);
After Navigation you can get your data:
string myTextData = NavigationService.GetNavigationData() as string;
This method has to disadvantages: it is not type-safe and your data won't be preserved in Tombstone mode.
As for the second disadvantage you can easily use PhoneApplicationService.State Property for the purpose of Page Navigation - it is a dictionary (which is preserved while tombstoning):
PhoneApplicationService.Current.State.Add("data", yourData);
Then when you want to get your data:
yourDataType yourData = PhoneApplicationService.Current.State["data"] as yourDataType;
There are also more ways in which you can pass the data.

How to create multiple components of a service with c'tor dependencies

I'd like to create several similar services which can be destinguished and accessed by their names (=keys).
For the service implementation I want to use classes with c'tor dependencies like this:
public interface IXYService
{
string Tag { get; set; }
}
public class _1stXYService : IXYService
{
public _1stXYService(string Tag)
{
this.Tag = Tag;
}
public string Tag { get; set; }
}
What I tried was to use 'AddComponentWithProperties' to have a concrete instance created which is accessible via a given key:
...
IDictionary l_xyServiceInitParameters = new Hashtable { { "Tag", "1" } };
l_container.AddComponentWithProperties
(
"1st XY service",
typeof(IXYService),
typeof(_1stXYService),
l_xyServiceInitParameters
);
l_xyServiceInitParameters["Tag"] = "2";
l_container.AddComponentWithProperties
(
"2nd XY service",
typeof(IXYService),
typeof(_1stXYService),
l_xyServiceInitParameters
);
...
var service = l_container[serviceName] as IXYService;
However, the dependencies were not resolved and hence the services are not available.
Using IWindsorContainer.Resolve(...) to populate the parameters is not desired.
Construction by XML works, but is not in all cases sufficient.
How could I achieve my goals?
If you're looking to define the Tag property at registration-time:
[Test]
public void Named() {
var container = new WindsorContainer();
container.Register(Component.For<IXYService>()
.ImplementedBy<_1stXYService>()
.Parameters(Parameter.ForKey("Tag").Eq("1"))
.Named("1st XY Service"));
container.Register(Component.For<IXYService>()
.ImplementedBy<_1stXYService>()
.Parameters(Parameter.ForKey("Tag").Eq("2"))
.Named("2nd XY Service"));
Assert.AreEqual("2", container.Resolve<IXYService>("2nd XY Service").Tag);
}