Create a Schema from an existing one? - sql-server

I have two databases:
database A with missing indexes,constraints,foreign keys etc ...
database B with all the missing features
I have loaded the schemas of the two databases in my C# code and after comparing them I added the missing features to the first schema.
Now I want to update that schema back to SQL Server. How to do that? Could I create a schema from an existing schema?
This is what I have tried:
public static void Compare(ref DbMetaData dbSchema , ref DbMetaData dbSchema2)
{
foreach (var schemaGroup in dbSchema.SchemasDic.Values )
{
DbUserSchemaInfo schemaGroup2=dbSchema2.SchemasDic.Values.First(sc => sc.SchemaName == schemaGroup.SchemaName);
foreach (var x in schemaGroup.TablesDic)
{
var y = schemaGroup2.TablesDic.First(sc => sc.Value.TableName == x.Value.TableName);
// GET the difference in columns
var colDiff = x.Value.Columns.Except(y.Value.Columns);
// GET the difference in indexes
var indexDiff = x.Value.Indexes.Except(y.Value.Indexes);
// GET the difference in constraints
var constraintDiff = x.Value.DfConstraints.Except(y.Value.DfConstraints);
// GET the difference in Fk
var foreignKeysDiff = x.Value.ForeignKeys.Except(y.Value.ForeignKeys);
//check if a primary key exists
var primaryKeysDiff = y.Value.PrimaryKey == null ? x.Value.PrimaryKey : null;
// GET the difference in triggers
var triggersDiff = x.Value.Triggers.Except(y.Value.Triggers);
//merge the difference
if (indexDiff.Count() != 0)
{
foreach (var index in indexDiff)
{
y.Value.AddTableIndex(index.Value);
}
}
if (constraintDiff.Count() != 0)
{
foreach (var constraint in constraintDiff)
{
y.Value.AddDefaultConstraint(constraint.Value);
}
}
if (foreignKeysDiff.Count() != 0)
{
foreach (var foreignKey in foreignKeysDiff)
{
y.Value.AddFk(foreignKey.Value);
}
}
if (triggersDiff.Count() != 0)
{
foreach (var trigger in triggersDiff)
{
y.Value.AddTableTrigger(trigger.Value);
}
}
}
}
//Update DbSchema in sqlserver
}

Related

Get array data and insert into database

I'm trying to get the data in the array that came from another function(that function is extracting the data in the csv file) and when i tried calling the two fields from that array it shows an error that it is unidentified variables.
The $this->csv_process(); as shown on the function action() is the function that extracts the data from the csv file and stores it in an array which is successful since I tried checking it on var_dump();
I also named the two fields as $name and $email as shown below:
Function CSV_process()
public function csv_process()
{
/* variables for openning the csv file */
if (!in_array($extension, $allowed_ext)) {
$this->session->set_flashdata("message", "Sorry, CSV file only.");
} else {
if ($filesize > 0) {
$file = fopen($filename, "r");
$toWrite = array();
$error = false;
$col_size = 2;
$skip = 0;
while ($data = fgetcsv($file, 10000, ","))
{
$skip++;
if ($skip == 1) {
continue;
}
$numofcol = count($data);
if ($numofcol != $col_size ) {
$this->session->set_flashdata("message", "Column count exceeded or missing.");
} else {
$name1 = $data[0];
$name = str_replace("'", "''", $name1);
$email1 = $data[1];
$email = str_replace("'", "''", $email1);
$toWrite[] = [
'name' => $name,
'email' => $email
];
}
}
}
}
return $toWrite;
}
Function Action()
function action(){
$toWrite[] = $this->csv_process();
foreach ($toWrite as $arr) {
list($name, $email) = $arr;
//die(var_dump($arr));
$query = $this->db->query("SELECT * FROM import WHERE name ='$name' AND email = '$email'");
if ($query->num_rows() >= 1) {
} else {
if ($name == "" OR $email == "") {
} else {
if ((filter_var($email, FILTER_VALIDATE_EMAIL)) == FALSE ) {
} else {
$this->db->query("INSERT INTO import(name, email, created_date) VALUES('".$name."', '".$email."', '".date("Y-m-d h-i-s")."')");
$this->session->set_flashdata('message', 'SUCCESS YEAY');
redirect('Clean_csv/index');
}
}
}
$query->free_result();
}
}
Listing arrays doesn't seem to work for here, anyone knows how to extract the data array from $arr?
You don't need to extract the values. You can use each $arr in a bound query. It simplifies the syntax for the select query.
For inserting use CodeIgniter's insert() method. Again, the $arr can be used directly by adding the date to it before the insert is attempted.
I think this will work.
function action()
{
$toWrite[] = $this->csv_process();
foreach($toWrite as $arr)
{
$query = $this->db->query("SELECT * FROM import WHERE name=? AND email=?", $arr);
if($query->num_rows() >= 1)
{}
else
{
if($arr['name'] == "" OR $arr['email'] == "")
{}
else
{
if((filter_var($email, FILTER_VALIDATE_EMAIL)) == FALSE)
{}
else
{
$arr['created_date'] = date("Y-m-d h-i-s");
$this->db->insert("import", $arr);
$this->session->set_flashdata('message', 'SUCCESS YEAY');
//??? redirect('Clean_csv/index');
//Are you sure, you may still have more $arr in $toWrite to process - right?
}
}
}
$query->free_result();
}
}
You need to know what a terrible idea it is to repeatedly run database queries inside a loop. Even though you use free_result() it could be a massive drain on server resources. If your csv file has several thousand items you are severely stressing the database and the server.

Covert Collection of Objects to Collection of Dictionary<string, object>

I'm fetching a large Amount of data from RIA Service. the return type have group of objects like RouteA, HistroyRouteA. HistroyLogRouteA all have records for different years with same Unique Key.
I have to Bind this data dynamically to a RadGridView. Always I have unknown columns in result.
For this I followed
http://blogs.telerik.com/vladimirenchev/posts/11-09-28/dynamic-binding-for-your-silverlight-applications.aspx
http://www.telerik.com/forums/rowdetailstemplate-binding-with-dynamic-data
And build My data Collection with Code :
private void OnShowPreviousYear(object parameter)
{
GridViewHeaderCell cell = parameter as GridViewHeaderCell;
var head = cell.Column.Header;
this.context.Load<Route>(this.context.GetRoutesQuery(), LoadBehavior.MergeIntoCurrent, OnRouteHistoryLoadComplete, null);
}
private void OnRouteHistoryLoadComplete(LoadOperation<Route> lo)
{
object ro = null;
if (lo.Entities != null)
{
this.context.Load<Routeshistory>(this.context.GetRouteshistoriesQuery(), LoadBehavior.MergeIntoCurrent, (lp) =>
{
Route recent = lo.Entities.FirstOrDefault();
int year =(int)recent.Hpmsyear-1;
var rows = this.context.Routes.Join(this.context.Routeshistories,
r => r.Routeid.ToString(),
h => h.Routeid.ToString(),
(r, h) => new { r, h });//.Where(t => t.r.Routeid == t.h.Routeid );
RoutesGridData = new ObservableCollection<DataRow>();
int count = 0;
foreach (var tmpR in rows)
{
//Debug.WriteLine(tmpR.r.Routeid + " -- " + tmpR.h.Routeid);
if (count < 50)
{
DataRow row = new DataRow();
if (tmpR.r is Route)
{
Type type = tmpR.r.GetType();
foreach (PropertyInfo info in type.GetProperties())
{
// Debug.WriteLine(info.Name + "--- NAME OF PRR");
var val = info.GetValue(tmpR.r, null);
if (!info.Name.Equals("EntityConflict")
&& !info.Name.Equals("ValidationErrors")
&& !info.Name.Equals("HasValidationErrors")
&& !info.Name.Equals("EntityState")
&& !info.Name.Equals("HasChanges")
&& !info.Name.Equals("IsReadOnly")
&& !info.Name.Equals("EntityActions"))
{
row[info.Name] = val;
}
}
}
// other tables...
RoutesGridData.Add(row);
}
count++;
}
}, null);
}
// var b = ro;
}
this code works fine for small record like 50 rows. but I when It try to convert all data it become slow. and screen crashes. I think this is because of Reflection. Is there any other way to convert my fetch data into Dictionary? Means I can map my table to dictionary in Entity Framework or Linq can do this for me without getting my code slow etc.
My Entities are mapped with EF 6 & I m using Deart oracle connector.
Due to reflection it was getting extremely slow so I did in during Linq query it's working for a while what data I have with me.
var rowss = this.context.Routes.Join(this.context.Routeshistories,
r => r.Routeid,
h => h.Routeid,
(r, h) => new DataRow(
(from x in r.GetType().GetProperties() select x).Where(x => x.Name != "EntityConflict"
&& x.Name != "ValidationErrors"
&& x.Name != "HasValidationErrors"
&& x.Name != "HasChanges"
&& x.Name != "EntityState"
&& x.Name != "IsReadOnly"
&& x.Name != "EntityActions")
.ToDictionary(x => x.Name, x => (x.GetGetMethod().Invoke(r, null) == null ? "" : x.GetGetMethod().Invoke(r, null))),
(from x in h.GetType().GetProperties() select x).Where(x => x.Name == head)
.ToDictionary(x => x.Name + "-" + year.ToString(), x => (x.GetGetMethod().Invoke(h, null) == null ? "" : x.GetGetMethod().Invoke(h, null))))
);// , new EqualityComparerString()
RoutesGridData = new ObservableCollection<DataRow>(rowss);

cakephp: creating new records from other controller

I'm going to create 50 temp/dummy rows inside my model database. My problems is how can I create and save new records in my DB? Assume my model Random containts columns (id,randomValue,...).
public function addNew() {
$this->autoRender = false; // We don't render a view in this example
$moduleSize = 50;
$count = $moduleSize;
while ($count > 0) {
$random_number = rand(1000000000, 9999999999);
//check if duplicate
if ($this->checkIfDuplicateSerial($random_number)) {
//nothing to be done
} else {
$this->Random->create(array('randomValue' => $random_number));
$this->Random->save();
$this->Random->clear(); //to init new one
$count--;
}
}
$this->response->body('Inserted' . $moduleSize . 'Random Numbers');
}

Strange error message when using SaveChanges in EF with MVC

I have a dropdownlistfor with values that is not from my database, and when a user select values that does not exist in my database, I want to save it to the database(and if it already exist, I just use the existing data).
This work fine with some of my data(see code for where it does not work)
This is my repository:
public void newPerson(Person addperson)
{
db.Person.AddObject(addperson);
db.SaveChanges(); //This wont work
}
here is my controller:
[HttpPost]
public ActionResult Create(CreateNKIphase1ViewModel model)
{
if (ModelState.IsValid)
{
var goalcard = new GoalCard();
var companyChecker = "";
var dbCompanies = createNKIRep.GetCustomerByName();
var addcustomer = new Customer();
foreach (var existingcustomer in dbCompanies)
{
companyChecker = existingcustomer.CompanyName;
if (existingcustomer.CompanyName == model.CompanyName)
{
var customerId = existingcustomer.Id;
var selectedCustomerID = createNKIRep.GetByCustomerID(customerId);
goalcard.Customer = selectedCustomerID;
break;
}
}
if (companyChecker != model.CompanyName)
{
addcustomer.CompanyName = model.CompanyName;
createNKIRep.newCustomer(addcustomer); //This works!
goalcard.Customer = addcustomer;
}
if (model.PersonName != null)
{
var Personchecker = "";
var dbPersons = createNKIRep.GetPersonsByName();
foreach (var existingPerson in dbPersons)
{
Personchecker = existingPerson.Name;
if (existingPerson.Name == model.PersonName)
{
var personId = existingPerson.Id;
var selectedPersonID = createNKIRep.GetByPersonID(personId);
goalcard.Person = selectedPersonID;
break;
}
}
if (Personchecker != model.PersonName)
{
Person newPerson = new Person();
newPerson.Name = model.PersonName;
createNKIRep.newPerson(newPerson);//Where repository is called
goalcard.Person = newPerson;
}
}
But when I try to save a new Person I get the following error message:
The conversion of a datetime2 data type to a datetime data type resulted in an out-of-range value.
The statement has been terminated.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Even though Person only have Id and name as attributes in my database.
Is there anything wrong in my code, or is it any setting in my database that has to be changed?
Thanks in advance.
It's because I use db.SaveChanges(); multiple times in one post. Reducing numbers of time I use db.SaveChanges helped me get rid of the error.

How to get name of a RavenDB document

My code is:
using (var session = documentStore.OpenSession(databaseName))
{
var list = session.Query<dynamic>("Raven/DocumentsByEntityName").ToArray();
foreach (var item in list)
{
Console.WriteLine(item);
}
}
But it does not give me the name of the document. I want to list all of the documents in single database.
Try something like this, it's a bit more generic and it allows access to the raw documents
using (var session = store.OpenSession())
{
//Issue a dummy query to make sure the indexing has finished
var dummyQuery = session.Query<dynamic>("Raven/DocumentsByEntityName")
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.ToList();
//First get all the document types, i.e. the different entity names
var docTypes = store.DatabaseCommands.GetTerms("Raven/DocumentsByEntityName", "Tag", "", 128);
foreach (var type in docTypes)
{
Console.WriteLine("\n{0}:", type);
//Might need to do paging here, can only get at most 1024 docs in 1 go!
var docs = store.DatabaseCommands.StartsWith(type, 0, 1024).ToList();
foreach (var doc in docs)
{
Console.WriteLine(" {0}: {1}", doc.Key, doc.ToJson());
}
}
}
modifying Matt waren's code for specified database.
public void DocumentNamesWithMetadata(string databaseName="1")
{
using (var session = documentStore.OpenSession(databaseName))
{
//Issue a dummy query to make sure the indexing has finished
var dummyQuery = session.Query<dynamic>("Raven/DocumentsByEntityName")
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.ToList();
//First get all the document types, i.e. the different entity names
var docTypes = session.Advanced.DatabaseCommands.GetTerms("Raven/DocumentsByEntityName", "Tag", "", 128);
foreach (var type in docTypes)
{
Console.WriteLine("\n{0}:", type);
//Might need to do paging here, can only get at most 1024 docs in 1 go!
var docs = session.Advanced.DatabaseCommands.StartsWith(type, 0, 1024).ToList();
foreach (var doc in docs)
{
Console.WriteLine(" {0}: {1}", doc.Key, doc.ToJson());
}
}
}
}

Resources