Bindable indexed in-Memory Data Scturcture - c#

I want to improve one of my current applications that uses ADO Data Sets. The application is standalone, no DBs. Almost everyone says that ADO Data set is an old stuff and a much better approach is using your own structures. For example I have the data model below (the same kind of model we usually use with Entity Framework):
public class Customer
{
public int ID {get;set;}
public string Value {get;set}
public IEnumerable<Order> Orders {get;set;}
}
public class Order
{
public int ID {get;set;}
public string Value {get;set}
public Customer Customer {get;set;}
}
I don't understand the next:
How to store class model in memory. Just in a simple List<>. It is not efficient with searching. In SQL we can make indexes for two often used columns and optimize our search. Can we do something similar (fast indexed search by multiple columns) in memory? If can, please explain me how. In DataTables we can use Primary Key as index.
Is a good data structure exist. A structure that allows binding to DataGrids, Fast indexed search by multiple columns, LINQ. Or we need to store everything in List<> or Hashset<> and prepare some additional structures for fast searching.

Related

C# MVC - Dynamic database architecture

I have an idea for a web app where I will want the user to create their own database through a web application, with their own table names and field types.
I thought about creating a database structure using Object Oriented Programming so that a pre-made database will support all kinds of Entities with custom properties. Something like this:
CustomType
{
public long TypeId {get;set;}
public string ActiveType {get;set;}
}
CustomProperty
{
public int wholeNumber {get;set;}
public string text {get;set;}
public bool boolean {get;set;}
public decimal dec {get;set;}
//Choosen Id of the type to work with
public long TypeId {get;set;}
public bool wholeNumber_ACTIVE {get;set;}
public bool text_ACTIVE {get;set;}
public bool boolean_ACTIVE {get;set;}
public bool dec_ACTIVE {get;set;}
}
CustomEntity
{
public string TableName {get;set;}
public CustomProperty Prop01 {get;set;}
public CustomProperty Prop02 {get;set;}
public CustomProperty Prop03 {get;set;}
public CustomProperty Prop04 {get;set;}
public CustomProperty Prop05 {get;set;}
}
The idea behind this is to let the user decide what they want their database to store, on a pre-made database for them to work with, without having to create it during runtime since this is a web app.
I believe I can manage it like this for them to store whatever they need, but I'm also thinking about the following issues:
How will I manage relationships when the user needs to link tables with Ids and foreign keys.
(I though about managing a public long ForeignId {get;set;} and just store the Id they need to associate).
How will I manage queries since tables will have CodeNames and each will have a different meaning for each person that sets it up.
(I though about, renaming the table during Runtime, but I'm afraid of errors and DB corruption).
Also thought about sending direct queries to create the database according to user's need, but then again non-experienced users can really mess up here or find it hard to manage.
How can I manage migration or DB changes with code instead of the use of PowerShell console.
If we have multiple users each with a unique database, but the same web app how can we manage webconfigs to work with this idea.
I know there's a lot of questions here, I'm looking for the best way to achieve this, having multiple users own their small web app through the internet using MVC pattern and lots of options through a browser.
I would recommend an Entity Attribute Value (EAV) pattern as a solution. With the EAV pattern, rather than creating new tables with new columns for every custom property you wish to store, you store those properties in rows. For example. Instead of every custom table being defined like this:
You define them like this instead:
This allows for flexible creation of multiple entities with multiple properties. The classes in your business logic will then be Entity classes with a collection of Property objects.
In case you haven’t spotted the trade-offs already, the limitation of using the EAV model is the inability to specify field types (int, varchar, decimal etc.), infact, all your property values will be stored as a single type (usually strings).
There are a number of ways to address this. Some handle all the validation etc. in the business logic, other create Field tables per type, so based on my example, rather than having just one EntityFields table, you’ll have multiple, separated by type.

Is it a good idea to store classes as settings items in sql?

I am doing this project in c# and when designing a database, i am using a rule that each class is basically sql table (at least the class that has to be persisted).
Since some classes are purely used to define business settings and the classes are rather flat, I am curios does it make any sense to do something like this..
Transform business layer class
class Contact
{
public string Name {get;set;}
public string PhoneNumber {get;set;}
public bool AcceptsTextMessages {get;set;}
public bool AllowedHoursForTextMessagesStart {get;set;}
public bool AllowedHoursForTextMessagesEnd {get;set;}
public List<DayOfWeek> SendMessagesOnlyOnWorkdays {get;set;}
}
to a data layer class that look something like (and persist it in sql)
public Settings
{
public ID {get;set}
public Name {get;set}
public Value {get;set;}
}
with real life data
ID Name Value
1 Name John Doe
2 PhoneNumber 01234657
3 ExceptsTextMessages true
4 AllowedHoursForTextMessagesStart 0
5 AllowedHoursForTextMessagesEnd 24
6 SendMessagesOnlyOnDays 1,2,3,4,5
The primary reason for this is to have one settings table instead of having as many tables as classes, possibly easier class modification, easier manipulation of properties between classes (in case there is a business logic need to move one property from one class to another)
Decomposing your objects into IDs and attribute-value pairs is one of those techniques that's sometimes extremely useful. EAV data is much more complicated to manage than a flat table with individual columns, so it's not something to implement lightly.
Given what you've posted, I probably wouldn't. All the fields you have seem reliably relevant to being-a-contact and unlikely to require changing around dynamically in production (since one starts or stops accepting text messages, rather than ascending to a plane of existence where text messages are epistemologically irrelevant).
Even if it made sense to represent certain fields as pairs, I'd only do it for those fields: keep a users table with a primary key and the essential data, then put the rest off in an EAV table with a foreign key relationship to users.

HQL to insert entity references by passing property values?

I'm having problems sorting through all the Google results for my search terms; too much information that is close but not what I'm looking for, so... off to StackOverflow!
I have three tables, Stocks, StockProperties, and StockPropertyTypes.
One Stock record has zero or more StockProperties associated with it, and has a unique column symbol. Each StockProperty record has exactly one reference to a StockPropertyType, and exactly one reference to a Stock. The StockPropertyTypes table has a unique column code. The entities for these tables do not have the FK id's for the references, just the classes. For example, the StockProperty entity looks like:
public class StockProperty
{
public virtual Guid StockPropertyId { get; set; }
public virtual Stock Stock { get; set; }
public virtual string PropertyValue { get; set; }
public virtual StockPropertyType Type { get; set; }
}
I want to pass into a method a stock symbol, a type code, and a value, and create a StockProperty record using HQL, but I'm not sure how to write that query. The Stocks table and the StockPropertyTypes have no relation. Seems like this should be some nested HQL query, but I'm not sure how to differentiate between a property and a referenced entity.
Can someone educate me what that HQL query should look like?
I should add, my goal here is to do this with one db trip; I don't want to load the Stock and StockPropertyType entities before creating the StockProperty record.
The typical way to do this is to load the Stock and StockPropertyType from the ISession. Then create a StockProperty to save using ISession.Save().
As you mention, this requires a few extra trips to the DB. One way to avoid this is to execute SQL directly as follows:
session
.CreateSQLQuery(#"insert
into StockProperty(StockSymbol, Value, TypeCode)
values (:stockSymbol, :value, :typeCode)")
.SetProperty("stockSymbol", stockSymbol)
.SetProperty("value", value)
.SetProperty("typeCode", typeCode)
.ExecuteUpdate();
You are kind of bypassing NHibernate here, but it is more efficient.
Personally, I would consider loading the related entities into memory unless you are experiencing a bottleneck. You can load both the Stock and StockPropertyType in a single DB call by using the Future<T>() paradigm.
Alternatively...
You could try fiddling with <sql-insert> inside of your hibernate mapping file. This allows you more control over how the insert is generated. You might want to add some properties StockId and StockPropertyTypeId that are only used during insert.

Map queries to multiples entities with Database First EF5 and view them in a DataGrid

I'm doing my first steps with Database First EF5 and I'm trying to reproduce my knowledge from the classical DataTable, DataAdapter, etc.. in EF5 ORM paradigm but I'm stuck:
I use to work a lot with DataGridsViews and Trees and fill them with Stored Procedures. The information that I use to display correspond with more than 1 table/entity.
For example, supposing a blog app. with posts, users, etc. like this:
Tables:
Post {Id, Subject, Body, Date, Author}
User {Id, Name, Email, Pwd}
And for joining all the tables and calculating some values we have an StoredProcedure. This SP returns attributes from Post and User tables and 2 run-time calculated values:
Post.Subject, Post.Body, Post.Categories, User.Name, DaysSincePublished, IsAuthorOnline
Or to make it easier:
Post.*, User.*, DaysSincePublished, IsAuthorOnline
Questions:
Is it possible to fit the previous record set in a multiples entities at once (Post and User)? And fill with it a DataGridView?
Is it possible to fit it in a entity created on-the-fly? And in that case is it possible to update (bind) it form the DataGridView.
Am I doing a wrong approach to the problem?
I have tried methods like Context.ObjectContext.Translate<TEntity>() or Context.Database.SqlQuery<TEntity>(storedProcedure, parameterArray); but only returns 1 entity at time.
Note:
With this example is it possible to forget about the StoredProcedure and make a linq query. But in the real scenario I have queries with more than 10 tables, and sub-queries, few times without FK, ... and caring a lot about server performance the stored procedure is a Must.
Well, your question is quite vague, anyway...
To use correctly an ORM, like EF, I think it's a good thing to understand as well SQL world than object world.
So, let's say you have two classes corresponding to your tables :
I imagine that you will use Database first, not Code First or Model First.
When using EF, classes will be generated from your db.
something like that :
public partial class Post {
public int Id {get;set;}
public string Subject {get;set;}
public string Body {get;set;}
public DateTime Date {get;set;}
//etc.
public virtual User Author {get;set;} //this is what's called a Navigation proeprty, which will help you to find relations with your User class.
}
public partial class User {
public int Id {get;set;}
public string Name {get;set;
public IList<Post> Posts {get;set;}//Navigation property from User to Post class. It's a list, reflecting the one-to-many from Post to User.
}
Now, for calculated properties, you can do this in a few ways.
One would be to create another part of the partial class Post
public partial class Post {
public int DaysSincePublished {get {return (DateTime.Now - Date).Days;}}
}
Then, you can use a simple query like that, saying you have
public DbSet<User> Users {get;set;}
public DbSet<Post> Posts {get;set;}
Then
var myQuery = context.Users.Include(m => m.Posts);
var list = myQuery.ToList();//this will get data from your db.
in list, you've got all the fields you need, including the "calculated properties" (well, you've got all from Post and User, which maybe more than what you really need, in fact).
To avoid retrieving all, you may use select data in an anonymous type (or a custom class)
var myQuery = context.Posts.Select(m => new {
subject = m.Subject,
body = m.Body,
userName = m.User.Name,
daysSincePublished = SqlFunctions.DiffDays(m.Date, DateTime.Now)//see another way to get calculated value
});
var list = myQuery.ToList()//retrieving only the required fields from db.
And the argument of "my real needs are too complicated for an ORM" doesn't make that much sense. Anyway, you will still be able to use SP when needed, or even raw sql. The goal is too be pragmatic, but investigate a little bit before coming to a definitive conclusion;)

NHibernate, WCF, WPF architectural issues

I want to display a bunch of different data objects that I have using WPF. These data objects vary in data. They have common properties, but they also have some differing properties. There will be a "master" class that references these entities. Each master class can have one of each of these data types.
I'm finding it difficult to design them even on a database level. Should I have one table per data object, thereby making it easy to get the data using NHibernate (just reference one of these entities). This makes it quite difficult to consume using WCF though. If I'm wanting to display this data in WPF, I'll probably need a collection of some variety, and that's what I don't have.
I could put all data types into the same table and have a multi-column unique constraint on the owner id and data type id. But then I may have null properties in my entities, and it would also be hard to display in the UI. It would also complicate editing the entities, as I'd have to mindful of which properties the user can and can't edit.
I guess visually, the entities would look like this in the first way:
public class Master
{
int Id
DataType1 Data1
DataType2 Data2
}
public class DataType1
{
int Id
string SomeString
string AnotherString
}
public class DataType2
{
int Id
string SomeString
string DifferentString
}
And this in the second way:
public class Master
{
int Id
List<DataType> Types
}
public class DataType
{
int Id
string SomeString
string AnotherString
string DifferentString
}
So which would be the best way? Or is there a different way that's better than both (there probably is)?
It is really depend on your business case as it is not such an architectural issue. If you have known number of DataType-s do static (one to one) reference (first example).
If you have unknown or dynamic number of the DataType-s you have no other option than to make these DataType-s as a list in your "Master" object.

Categories