accessing Altering & querying Sql Server 2005 Table by a table-id or table-index - sql-server-2005

Is there any way to address/refer to a SQL SERVER table, by its Unique Index rather its TableName ?
my Application is using multiple html tables, which are acutally within a form,
for CRUD opporations,(more R/U than Create or delete) of an Existing SQL Table.
now... that i need to mix two separated tables, in same update-form (that's my first 'mix')
as i am using Jquery to pass parameters to C# code behind, so it will take care of the
update opporations, and will be able to differentiate the source of the update post/request
and i do know, i could address the table by its TableName,
i just wanted to make sure, as i was searching for some information on the web,
i've encountred results with the Terms sql server 2005... table index or id,
though all results seem to have something to do with, what i can call, some kind of "manipulation", in oreder to create some indexing system /schema (i think it's like hdds has a FAT table)
and I Emphasize "Create",cause I was actualy looking for an existing /built in, numeric value for a "TableID", just the same as a Table has rows and each row has its row IDENTITY - Column.
so at this point i am turning back to the real question at the top .

so that's what i came up with aventually : a simple struct + a class to hold values for database
public class DBMetaDetails
{
public struct DbTable
{
public DbTable(string tableName, int tableId): this()
{
this.Name = tableName;
this.ID = tableId;
}
public string HtmlOutput;
public string Name { get; private set; }
public int ID { get; private set; }
}
}
public sealed class tblsIDs
{
public const int firstTbl= 1, SecondTbl = 2;
}
another class should be for table names
public sealed class tblsNames
{
public const string firstTbl= "firstTbl", SecondTbl = "SecondTbl";
}
another that will hold tables columns names ...etc

Related

Best practice to retrieve Json value stored in sql table through c# code

I have a JSON value stored in SQL Server. I want to retrieve that JSON value and bind it to C# property (which is deserialized to desired entity). I want to know what would be the best practice to do that effectively? Right now, I'm doing like this:
Public class Employee
{
public int Id;
public string Name;
public int Age;
}
Public class EmployeeData
{
public string JsonEmployeeText {get;set;} // Binding the json string from database
public List<Employee> Employees { get { return JsonConvert.DeserializeObject<Employee>(JsonEmployeeText );}} //Converting the retrieved json string from Database to c# entity
}
I guess we should not do any sort of database logic on getters as it can sometimes delay the process of initialization in case we need to use this we need to make sure we enable the lazy loading

How to write dynamic SQL Queries in Entity Framework?

I have a page where the user can input a SQL query. This query can be against any table in my database. I need to execute this query against the corresponding table and show the result in my view. How to do this?
For eg: user can input Select * from ABC or select max(price) from items.
I tried:
var results = DbContext.Database.SqlQuery<string>(query).ToList();
But this throws an error:
The data reader has more than one field. Multiple fields are not valid
for EDM primitive or enumeration types.
Whatever the result I should be able to pass it to the view and display it.
Please help.
The error message states the problem exactly:
The data reader has more than one field. Multiple fields are not valid for EDM primitive or enumeration types.
To correct the problem, you can either submit a SQL string that returns a single string column from the database, or supply a type parameter that allows EF to map multiple columns.
For example:
SELECT someStringColumn FROM ABC
OR
var results = DbContext.Database.SqlQuery<MyDto>(query).ToList();
Where MyDTO looks something like this:
class MyDto
{
public int AddressID { get; set; }
public string Address { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Zip { get; set; }
}
you can use
SqlQuery<dynamic>"
this will resolve the error but you will only be able to get the count of the result returned. So you can just verify the query has returned some data. But still will need to know the type of the returned data.
It is a risk of providing the user to input query to database.

nHibernate Criteria, trying to order by enum name (alphabetical rather than value)

Lets say I have a class that contains a status type, which is defined as an enum like so:
public class MyObject
{
public virtual int Id { get; set; }
public virtual SomeEntity Data { get; set; }
public virtual MyStatusEnum Status { get; set; }
}
public enum MyStatusEnum
{
Active = 1,
Paused = 2,
Completed = 3
}
My mapping done via Fluent nHibernate looks like:
public class MyObjectMap: ClassMap<MyObject>
{
public MyObjectMap()
{
this.Table("my_object_table");
...
this.References(x => x.SomeEntity).Column("some_entity_id").Not.Nullable();
this.Map(x => x.Status).Column("status_type").CustomType<MyStatusEnum>().Not.Nullable();
}
}
Now that the setup is out of the way, my dilemma:
In my repository class, I want to sort all of the MyObject entities by the Status property, which nHibernate persists as an int. However, due to powers beyond my control, I cannot reorder MyStatusEnum so that the enum values are ordered alphabetically. When I create my criteria to select the list of MyObjects, and try to sort it by the Status property, it sorts by the int value of Status.
ICriteria criteria = this.Session.CreateCriteria<MyObject>("obj")
.AddOrder(Order.Asc("Status"))
.List()
I'd really like to be able to order by the enum name. Any ideas would be greatly appreciated.
If you want to sort it in the database, you'd have to sort by a projection with a case statement, but this won't be able to use an index, and might not work depending on your version of NHibernate (there are bugs when sorting by projections that aren't in the select).
Something like this might work:
.AddOrder(Order.Asc(
Projections.SqlProjection(
"CASE {alias}.Status "
+ "WHEN 1 THEN 0 "
+ "WHEN 2 THEN 3 "
+ "WHEN 3 THEN 2 END",
new string[0], new IType[0])))
Another option (better for performance) is to add a property to your class such as StatusOrder which you set equal to the relative position of the current status in your enum and just sort by that field (which you can index).
Yet another option is to define a formula property on your class (ie. specify a formula in the mapping) where the formula specifies a value to sort by depending on the status.
The easy way is to simply refactor your enum so that values and names have the same ordering:
public enum MyStatusEnum
{
Active = 1,
Paused = 3,
Completed = 2
}
But you can always use the List.Sort method to do the job:
enum MyEnum
{
Alpha,
Beta,
Gama
}
static void Main(string[] args)
{
List<MyEnum> list = new List<MyEnum>()
{
MyEnum.Gama,
MyEnum.Beta,
MyEnum.Alpha
};
list.Sort((x, y) => x.ToString().CompareTo(y.ToString()));
}
NHibernate sorts result sets based on how they are stored in the database. From what you said I'm guessing your enums are being stored as integers, hence you won't be able to ask SQL Server to order them by their names because these names are not known by SQL Server.
Unless you store your enums as strings, like discussed in this SO Question, your only option will be to perform the ordering "in memory" and not in the database.

How to create a NHibernate proxy object with some initiliazed fields (other than Id)?

I want to create an object proxy, similar to what ISession.Load is returning, but with some fields initialized. For other properties, when accessed, the proxy will fetch the entire object from database.
Consider the following example:
public class User
{
protected User() {
}
public User(int id, string username, string email) {
// ...
}
// initialize the following fields from other datasources
public virtual int Id { get; set; }
public virtual string UserName { get; set; }
public virtual string Email { get; set; }
// the rest of fields when accessed will trigger a select by id in the database
public virtual string Field1 { get; set; }
public virtual string Field2 { get; set; }
public virtual DateTime Field3 { get; set; }
public virtual ISet<Comment> Comments { get; set; }
}
The Id, UserName, Email are well-known in my case, so I could create an object proxy containing these fields, and for the others leave the default proxy behavior. In addition to throwing an exception if this id is not found in the database, i could throw an exception if preinitialized fields do not match or overwrite them silently. I am using NHibernate.ByteCode.Castle for proxy factories.
Edit:
The purpose for this is to be able to have some projection properties from an entity which can be queried elsewhere (say. a lucene index) and to avoid database calls. Then instead of wrapping these fields in a custom component class containing only these subset of properties, I want to use the proxy object directly so that I am able to load the rest of fields if needed. In the best case scenario I wouldn't hit the database at all, but in some corner cases I'd like to access other fields, too. The SELECT N+1 problem's impact can be greatly reduced by using batching.
An hypothetical version of code I want to use would be:
// create User object proxy with some fields initialized
var user = Session.Load<User>(5, new { UserName = "admin", Email = "admin#company.com" });
Console.WriteLine(user.Id); // doesn't hit the database
Console.WriteLine(user.UserName); // doesn't hit the database
Console.WriteLine(user.FullName); // doesn't hit the database
if (somecondition) {
Console.WriteLine(user.Field1); // fetches all other fields
}
You can specify an eager fetch inside the query to actually retrieve the needed associations. This could be done in different ways depending on what query style ( Criteria,Hql or LINQto NH ) you are using. But the key is changing the fetch mode.
for non-collection properties, I wouldn't do that;
the cost of prefetching them from the DB when you load your entity is (usually) so small that I wouldn't even bother.
for collection properties, just mark the collection fetch strategy as 'lazy=true'.
The only case where I would think about doing something like that is when I have a very large number of properties which I don't need (in your example- say Field1..Field20).
In that case I would either:
1. Define those properties together as a component, or
2. create a DTO for fetching only a subset of your entity's properties.
specifying lazy = "true" (or Not.LazyLoad() for Fluent NHib) on properties Field1, Field2, Field3, Comments mappings may help, though not sure about Select N+1 issue.
another way to go is specifying lazy = "false" for UserName, Email

Fluent NHibernate Map Enum as Lookup Table

I have the following (simplified)
public enum Level
{
Bronze,
Silver,
Gold
}
public class Member
{
public virtual Level MembershipLevel { get; set; }
}
public class MemberMap : ClassMap<Member>
{
Map(x => x.MembershipLevel);
}
This creates a table with a column called MembershipLevel with the value as the Enum string value.
What I want is for the entire Enum to be created as a lookup table, with the Member table referencing this with the integer value as the FK.
Also, I want to do this without altering my model.
To map an enum property as an int column, use method CustomType.
public class MemberMap : ClassMap<Member>
{
Map( x => x.MembershipLevel ).CustomType<int>();
}
In order to keep the enum and lookup table in sync, I would add the lookup table and data to your sql scripts. An integration test can verify that the enum and lookup table values are the same.
If you wanted SchemaExport to create this table, add a class and mapping for it.
public class MembershipLevel
{
public virtual int Id { get; set; }
public virtual string Code { get; set; }
}
public class MembershipLevelMap : ClassMap<MembershipLevel>
{
Id( x => x.Id );
Map( x => x.Code );
}
If you are creating the table with SchemaExport, you will need to populate it as well:
foreach (Level l in Enum.GetValues( typeof( Level ))) {
session.Save( new MembershipLevel{ Id = (int) l, Code = l.ToString() });
}
I wouldn't do that because your Enum declaration is not dynamic, or simpler, it doesn't change without recompiling, while your lookup table may change at any moment. If the Enum's and lookup table's values don't match, what's next?
Another reason is if you change the Enum (in code), you'd have to synchronise it with the database table. Since Enums don't have an incremental key (PK), they can't be synchronised so simple. Let's say you remove one Enum member from your code and recompile it, what is supposed to happen? And if you change a value?
I hope I made my objections to this approach clear. So I strongly recommend storing the name or the value of your enum members. To store it by name, just map like this:
public class MemberMap : ClassMap<Member>
{
Map(x => x.MembershipLevel, "level")
.CustomType<GenericEnumMapper<Level>>()
.Not.Nullable();
}
To store the values, do as #Lachlan posted in his answer.
Or if you really need a lookup table and wants to use an Enum with strict checking, create a normal model with PK (or use value for this), KEY and VALUE. Create your enum with your static members, and make the application query the database for the names and values when you start it. If things don't match, do whatever you need. Additionally, this doesn't guarantee your table won't change while your program is running, so you better be sure it doesn't.