I'm new to designing database stuff hands on, and rather than use new features like Linq to Entities code first, I'd like to implement the lower level stuff myself.
If I had a class Foo, which can contain any other number of Foos, it may look something like this:
class Foo
{
int FooId;
List<Foo> containedFoos;
...
}
Suppose the Foo table looks like
FooId, FooName, ContainingFooId (Foreign key to same table)
If I used code first and retrieved all my Foos, their containedFoos list would be automatically populated for me.
My question is, is this done on the applicaiton side (just do a straight select from the Foo table, and code the logic in C# to consruct a Foo, find all its containedFoo, build a list, etc)
or, is there way SQL Server can return the data in a more useful way? Such as returning each Foo and its contained items together in some way?
No, SQL Server won't return the data like that. You would have to create your objects and populate them by hand to mimic the way Code First populates your objects.
This reason alone makes EF very attractive (to me) to use from the beginning of a project. It saves TONS of time.
Related
I'm following Postgres documentation https://www.postgresql.org/docs/8.2/xfunc-c.html for writing C function and creating the extension (for hierarchial clustering) and I'm confused.
So I can get a tuple by using HeapTupleHeader t = PG_GETARG_HEAPTUPLEHEADER(0);
How can I get attribute values in this tuple? We have GET_ARGUMENT_BY_NUM, can I get a value for each column and put it into an array? (For some reason i want to get data from table and for example, clusterize it).
There is an example of using specific table for a function (emp table). How can I use random table for my function (I couldn't find the example)?
Is c_overpaid(emp, limit) (in documentation) called one time for emp table, or is it called as much as the rows in the table?
for hierarchical-clustering: can I get table data from postgres, write it into a temp file, read that file, put it into array, clusterize it and put the result into database? (like create or alter table and do a partitioning? like this: hub - is whole table, part_1 is one cluster, part_2 is the second one etc)
You should read the documentation for the current version.
Yes.
As the example shows, with GetAttributeByName, but there is also a GetAttributeByNum function. I assume you are talking about a C array and not a PostgreSQL array. You can stuff all the values into an array, sure, if they have the same data type.
Then you would have to use the special type record. For a code sample, look at the functions record_to_json and composite_to_json in src/backend/utils/adt/json.c.
It is called for each row found, since it appears in the SELECT list.
That's a bit vague, but sure. I don't see why you'd want to extract that from a table though. Why not write your own table access method, since it looks like you want to define a new way of storing tables.
But be warned, that would be decidedly non-trivial, and you'd better first get your feet wet with more mundane stuff.
Is there a way to use multimapping in Dapper in a generic way, without using custom SQL embedded in C# code?
See for example
Correct use of Multimapping in Dapper
Is there a generic way to query the data from 2 related entities, where common fields are determined automatically for join?
Don't do this. Don't even think this way! Databases are long lasting and normalized. Objects are perishable and frequently denormalized, and transitioning between the two is something to do thoughtfully, when you're writing your SQL. This is really not a step to automate. Long, painful experience has convinced many of us that database abstractions (tables and joins) should not just be sucked into (or generated out of) code. If you're not yet convinced, then use an established ORM.
If, on the other hand, you absolutely want to be in control of your SQL, but its the "embedding" in string literals in C# that bugs you, then I couldn't agree more. Can I suggest QueryFirst, a visual studio extension that generates the C# wrapper for your queries. Your SQL stays in a real SQL file, syntax validated, DB references checked, and at each save, QueryFirst generates a wrapper class with Execute() methods, and a POCO for the results.
By multi-mapping, I presume you want to fill a graph of nested objects. A nice way to do this is to use one QueryFirst .sql per class in your graph, then in the partial class of the parent, add a List of children. (QueryFirst generated POCOs are split across 2 partial classes, you control one of them, the tool generates the other.)
So, for a graph of Customers and their orders...
In the parent sql
select * from customers where name like #custName
The child sql
select * from orders where customerId = #customerId
In the parent partial class, for eager loading...
public List<Orders> orders;
public void OnLoad()
{
orders = new getOrders().Execute(customerId); // property of the parent POCO
}
or for lazy loading...
private List<Orders> _orders;
public List<Orders> orders
{
get
{
return _orders ?? _orders = new GetOrders().Execute(customerId);
}
}
5 lines of code, not counting brackets, and you have a nested graph, lazy loaded or eager loaded as you prefer, the interface discoverable in code (intellisense for the input parameter and result). Their might be hundreds of columns in those tables, whose names you will never need to re-type, and whose datatypes are going to flow transparently into your C#.
Clean separation of responsibilities. Total control. Disclaimer : I wrote QueryFirst :-)
Multimapping with Dapper is a method of running multiple SQL queries at once and then return each result mapped to a specific object.
In the context of this question, Multimapping is not even relevant, re: you're asking for a way to automatically generate a SQL query from the given objects and creating the correct joins which would result in a single SQL query which is not related to Multimapping.
I suspect what you're looking for is something along the lines of the Entity Framework. There are a couple of Dapper extension projects you may want to look into which will generate some of your SQL. See: Dapper.Rainbow VS Dapper.Contrib
I am new to SQL Server and I would like to know how to return the exact columns of tables in UDFs.
The situation is like this : I am going to query a table and then return it again as table.
Example :
create function test
var t
set t = select * from table where condition
return t;
How am I going to do it?
(question is only how to return the table with dynamic fields)
Hope you understand the question. Thanks in advance
UPDATE : my question is somehow like how do I create a table variable where its columns are dynamic.
User defined functions have several limitations (they are meant not to have side-effects - cannot anything in the database - etc.). For your particular case, the following prohibit you to do your work:
dynamic SQL cannot be used
temporary tables are not allowed
So, a function can only work if it knows what is the structure of the result at compile time.
I would consider a procedure to achieve what you need, since it allows more flexibility. However, this comes with the headache of sharing data between stored procedures.
It is not specified in the question, but ideally, this dynamic processing should stay in a high level language like C# or Java that have more support for dynamic structures (e.g. LINQ or Dynamic LINQ in C#)
I have been developing programs in VB.NET for a few years and am familiar with it. The area where I do not have a lot of exposure is databases.
I am writing a program (for my personal use) called movie manager. It will store information on movies I have. I have selected Sql Server Compact Edition database. Assume I have a database with two tables namely Info and Cast. Info table has a few columns such as movie_name, release_date and so on. Cast table has few cols such as first_name,last_name etc.
Right now I have created a DataSet which reads all the info of tables from database (opens connection, fills tables info, closes connection). This way in a global variable I have a snapshot of database.
My queries :
Once I have data with me, every time I need to add, edit or delete a record I have to open a connection, fire an sql and close the connection. Right ? Is there a way to do this without using Sql ? Plus is this concept okay.
Since I am not using structures so I need to create empty datasets to store temp information. Is this convenient ?
If I have to search for a specific thing in dataset table, then do I have to loop thru all items or can I use sql on dataset or is there an alternate ?
1)Once I have data with me, every time I need to add, edit or delete a record I have to open a connection, fire an sql and close the connection. Right ? Is there a way to do this without using Sql ? Plus is this concept okay.
No. To update a database, you have to use the database. Create a stored procedure in the database to handle your functionality and then call it from the code and pass in whatever data needs saved. DO NOT USE INLINE SQL. Paramterized stored procedures are the way to go.
2) Since I am not using structures so I need to create empty datasets to store temp information. Is this convenient ?
It depends on what you're doing. I would create an object model to retain my updated data and then I'd pass the properties into the stored procedure when it was time to save my changes.
3) If I have to search for a specific thing in dataset table, then do I have to loop thru all items or can I use sql on dataset or is there an alternate ?
You can loop the rows or you can use linq to pull what you need out. Linq is really nice as it's basically .NET coded queries against a collection.
There are plenty of tutorials/guides out there to show you how to update via stored proc call form your code. There are a ton of linq tutorials as well. Basically, a linq query against your table will look something like:
dim result as Generic.List(of String) =
(from r in table.AsEnumerable()
select r
where r["columnName"] = "the value").ToList()
This syntax is probably a bit off, but it looks something like that.
Edit
Your Model:
Public Class EmployeeModel
Public Property Id
Public Property FirstName
Public Property Last Name
Public Property JobCode
Public Sub EmployeeModel(your params)
//set properties
End Sub
End Class
Your DAL:
Public Shared Class EmployeeDAL
Public Shared Sub SaveEmployee(ByRef model as EmployeeModel)
// call your sp_SaveEmployee stored procedure and set the parameters to the model properties
// #id = EmpoyeeModel.Id
// #JobCode = Employee.JobCode
// ...
End Sub
End Class
I use VB every few months, so there are probably some small syntax errors in there. But that's basically all you need to do. The function to save your data is in the DAL, not in the class itself. If you don't want to use a DAL, you can put the save functionality in your class, though. It'll work the same way, it's just not as clearly separated.
On your Questions.
number 1: You have to connect to database in order to store and retrieve data. There are lots of ways on how to deal with it and one way of it is to use app.config or you may simply create a function that calls the connection every time you need it.
number 2: Since you are dealing with dataset here are some tips you might want to look at DataSet
number 3: You can also try using Data Adapter and Data Table. I am not sure what you meant by your question number 3.
Cheers
I have problem with the way you are using your database and the ram of your computer.
Problem1: since you already have a database for holding the movies information why are you again holding the same information in memory?, creating an extra overhead. if your answer is for performance or i have cheap memory then why don't you use xml or flatfile instead? Database is not needed with this senario.
Problem2: You are like a soldier who dosent know about the weapon he use? right? because you are asking silly questions your first question about opening connection.. the answer is yes you have to open the connection every time save/read the data and close it as soon as possible.
your second question about convinent the answer is no. instead create class with all field as property and some method for initialization,saving,deleting. this way you have to write less code. nad suppose you have a movie names xyz there can be another movie xyz how will you distinguish it? if you have whole information b4 you you can do it via release date ,casts etc, but still it will be hard, so create a primary key for both your table
and finally your 3rd question , it will be easier to use use sql queries than looping thru the dataset(get rid of the dataset as soon as possible)
wish yu good luck on the road to rdbms
Let's say you have a table containing articles and you want want to display a list of them, excluding the actual article text. When you get a list of the article objects using LINQ or the Entity Framework, is there a LOT of overhead associated with getting that text column too? I assume that when you start enumerating the list, the article text will be stored in memory until the objects are disposed of.
So would it make sense to create an intermediary object that doesn't contain the text column? If so, how would you do this? Make a class inside your DAL, allow the ORM to automatically create one by setting up a stored procedure, or some other process?
The overhead isn't huge (just the cost of sending the data over the wire), but if you don't need the data sure, don't return it. I find the easiest way is to use anonymous types:
from a in Context.Articles
select new {Name = a.Name, Author = a.Author};
Since you're not actually materializing any Article instances, the Entity Framework won't need to fill out all the properties of an instance.
If you don't need the data you should definitely create a different type. By convention I typically name this sort of class "nnnInfo" or "nnnListItem". To create ArticleListItem, in L2S, simply drag the table to your DataContext designer a second time. Then rename it from 'Article1' to 'ArticleListItem' and remove the unneeded properties (rt click, delete). In EF, the process would be similar. As Craig notes, you could use anonymous types, but by creating a concrete type, you can reuse throughout your app, expose via services, etc.
A second way to do this would be to create the class manually and write an extension method to return ArticleListItem:
public static IQueryable<ArticleListItem> ToListItems(this IQueryable<Article> articles)
{
return from a in articles select new ArticleListItem{ Title = a.Title, ...}
}
This would allow you to "cast" any queries against Article as ArticleListItem...