How to get all values in a column in table using vaadin SQLContainer - vaadin

Hi Stackoverflow members,
I have one SQLContainer with TableQuery. Now, I want to get all the values in one column. How can I get it? Or Shall I need to go with FreefromQuery?
This is my SQLContainer code
public SQLContainer getMyContainer() {
//FreeformQuery query = null;
SQLContainer container = null;
try {
connectionPool = new SimpleJDBCConnectionPool(
"com.mysql.jdbc.Driver",
"jdbc:mysql://localhost:3306/vaadin", "root", "root",
2, 5);
TableQuery query = new TableQuery("components", connectionPool);
/*query = new FreeformQuery(
"SELECT rowNum, colNum, caption, cType FROM items where screenId='"
+ screenName+"'", connectionPool);
query.setDelegate(new DemoFreeformQueryDelegate());*/
container = new SQLContainer(query);
} catch (Exception e) {
}
return container;
}

It depends on what you wish to do.
With SQLContainer you could do it this way:
// Returns a list with all ID's (Beware of large resultsets)
Collection<?> itemIDS= conatiner.getItemIds();
for (Object itemID : itemIDS)
{
Property property= container.getContainerProperty(itemID, "COLUMN");
Object data= property.getValue();
}
The getItemIds() must fetch all rows from the DB (at least the primary keys),
so this will cause troubles with large resultsets/tables.
https://vaadin.com/api/com/vaadin/data/util/sqlcontainer/SQLContainer.html#getItemIds%28%29

Related

Best Way to Update only modified fields with Entity Framework

Currently I am doing like this:
For Example:
public update(Person model)
{
// Here model is model return from form on post
var oldobj = db.Person.where(x=>x.ID = model.ID).SingleOrDefault();
db.Entry(oldobj).CurrentValues.SetValues(model);
}
It works, but for example,
I have 50 columns in my table but I displayed only 25 fields in my form (I need to partially update my table, with remaining 25 column retain same old value)
I know it can be achieve by "mapping columns one by one" or by creating "hidden fields for those remaining 25 columns".
Just wondering is there any elegant way to do this with less effort and optimal performance?
This is a very good question. By default I have found that as long as change tracking is enabled (it is by default unless you turn it off), Entity Framework will do a good job of applying to the database only what you ask it to change.
So if you only change 1 field against the object and then call SaveChanges(), EF will only update that 1 field when you call SaveChanges().
The problem here is that when you map a view model into an entity object, all of the values get overwritten. Here is my way of handling this:
In this example, you have a single entity called Person:
Person
======
Id - int
FirstName - varchar
Surname - varchar
Dob - smalldatetime
Now let's say we want to create a view model which will only update Dob, and leave all other fields exactly how they are, here is how I do that.
First, create a view model:
public class PersonDobVm
{
public int Id { get; set; }
public DateTime Dob { get; set; }
public void MapToModel(Person p)
{
p.Dob = Dob;
}
}
Now write the code roughly as follows (you'll have to alter it to match your context name etc):
DataContext db = new DataContext();
Person p = db.People.FirstOrDefault();
// you would have this posted in, but we are creating it here just for illustration
var vm = new PersonDobVm
{
Id = p.Id, // the Id you want to update
Dob = new DateTime(2015, 1, 1) // the new DOB for that row
};
vm.MapToModel(p);
db.SaveChanges();
The MapToModel method could be even more complicated and do all kinds of additional checks before assigning the view model fields to the entity object.
Anyway, the result when SaveChanges is called is the following SQL:
exec sp_executesql N'UPDATE [dbo].[Person]
SET [Dob] = #0
WHERE ([Id] = #1)
',N'#0 datetime2(7),#1 int',#0='2015-01-01 00:00:00',#1=1
So you can clearly see, Entity Framework has not attempted to update any other fields - just the Dob field.
I know in your example you want to avoid coding each assignment by hand, but I think this is the best way. You tuck it all away in your VM so it does not litter your main code, and this way you can cater for specific needs (i.e. composite types in there, data validation, etc). The other option is to use an AutoMapper, but I do not think they are safe. If you use an AutoMapper and spelt "Dob" as "Doob" in your VM, it would not map "Doob" to "Dob", nor would it tell you about it! It would fail silently, the user would think everything was ok, but the change would not be saved.
Whereas if you spelt "Dob" as "Doob" in your VM, the compiler will alert you that the MapToModel() is referencing "Dob" but you only have a property in your VM called "Doob".
I hope this helps you.
I swear by EntityFramework.Extended. Nuget Link
It lets you write:
db.Person
.Where(x => x.ID == model.ID)
.Update(p => new Person()
{
Name = newName,
EditCount = p.EditCount+1
});
Which is very clearly translated into SQL.
Please try this way
public update(Person model)
{
// Here model is model return from form on post
var oldobj = db.Person.where(x=>x.ID = model.ID).SingleOrDefault();
// Newly Inserted Code
var UpdatedObj = (Person) Entity.CheckUpdateObject(oldobj, model);
db.Entry(oldobj).CurrentValues.SetValues(UpdatedObj);
}
public static object CheckUpdateObject(object originalObj, object updateObj)
{
foreach (var property in updateObj.GetType().GetProperties())
{
if (property.GetValue(updateObj, null) == null)
{
property.SetValue(updateObj,originalObj.GetType().GetProperty(property.Name)
.GetValue(originalObj, null));
}
}
return updateObj;
}
I have solved my Issue by using FormCollection to list out used element in form, and only change those columns in database.
I have provided my code sample below; Great if it can help someone else
// Here
// collection = FormCollection from Post
// model = View Model for Person
var result = db.Person.Where(x => x.ID == model.ID).SingleOrDefault();
if (result != null)
{
List<string> formcollist = new List<string>();
foreach (var key in collection.ToArray<string>())
{
// Here apply your filter code to remove system properties if any
formcollist.Add(key);
}
foreach (var prop in result.GetType().GetProperties())
{
if( formcollist.Contains(prop.Name))
{
prop.SetValue(result, model.GetType().GetProperty(prop.Name).GetValue(model, null));
}
}
db.SaveChanges();
}
I still didn't find a nice solution for my problem, so I created a work around. When loading the Entity, I directly make a copy of it and name it entityInit. When saving the Entity, I compare the both to see, what really was changed. All the unchanged Properties, I set to unchanged and fill them with the Database-Values. This was necessary for my Entities without Tracking:
// load entity without tracking
var entityWithoutTracking = Context.Person.AsNoTracking().FirstOrDefault(x => x.ID == _entity.ID);
var entityInit = CopyEntity(entityWithoutTracking);
// do business logic and change entity
entityWithoutTracking.surname = newValue;
// for saving, find entity in context
var entity = Context.Person.FirstOrDefault(x => x.ID == _entity.ID);
var entry = Context.Entry(entity);
entry.CurrentValues.SetValues(entityWithoutTracking);
entry.State = EntityState.Modified;
// get List of all changed properties (in my case these are all existing properties, including those which shouldn't have changed)
var changedPropertiesList = entry.CurrentValues.PropertyNames.Where(x => entry.Property(x).IsModified).ToList();
foreach (var checkProperty in changedPropertiesList)
{
try
{
var p1 = entityWithoutTracking.GetType().GetProperty(checkProperty).GetValue(entityWithoutTracking);
var p2 = entityInit.GetType().GetProperty(checkProperty).GetValue(entityInit);
if ((p1 == null && p2 == null) || p1.Equals(p2))
{
entry.Property(checkProperty).CurrentValue = entry.Property(checkProperty).OriginalValue; // restore DB-Value
entry.Property(checkProperty).IsModified = false; // throws Exception for Primary Keys
}
} catch(Exception) { }
}
Context.SaveChanges(); // only surname will be updated
This is way I did it, assuming the new object has more columns to update that the one we want to keep.
if (theClass.ClassId == 0)
{
theClass.CreatedOn = DateTime.Now;
context.theClasses.Add(theClass);
}
else {
var currentClass = context.theClasses.Where(c => c.ClassId == theClass.ClassId)
.Select(c => new TheClasses {
CreatedOn = c.CreatedOn
// Add here others fields you want to keep as the original record
}).FirstOrDefault();
theClass.CreatedOn = currentClass.CreatedOn;
// The new class will replace the current, all fields
context.theClasses.Add(theClass);
context.Entry(theClass).State = EntityState.Modified;
}
context.SaveChanges();
In EF you can do like this
var result = db.Person.Where(x => x.ID == model.ID).FirstOrDefault();
if(result != null){
result.Name = newName;
result.DOB = newDOB;
db.Person.Update(result);
}
Or you can use
using (var db= new MyDbContext())
{
var result= db.Person.Where(x => x.ID == model.ID).FirstOrDefault();
result.Name= newName;
result.DOB = newDOB;
db.Update(result);
db.SaveChanges();
}
For more detail please EntityFramework Core - Update Only One Field
No Worry guys
Just write raw sql query
db.Database.ExecuteSqlCommand("Update Person set Name='"+_entity.Name+"' where Id = " + _entity.ID + "");

How to call web API 2 in Eclipse

I have ASP.Net MVC 5 Web API project.
I cant use asp.net web API 2 web service in android
my web service is under mvc5, Then I have created mobile app in Eclipse Juno and i use Android sdk 21
below is my edited code
namespace AppServices.Models
{
public class AdvertisingRepository
{
private List<Advertising> Advertising = new List<Advertising>();
private int _nextId = 1;
public AdvertisingRepository()
{
}
public List<Advertising> GetAll()
{
Advertising.Clear();
SqlDataReader reader = null;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Server=.;Database=AppServices;User ID=sa;Password=123;";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "SELECT * FROM tblAdvertising";
sqlCmd.Connection = myConnection;
myConnection.Open();
reader = sqlCmd.ExecuteReader();
Advertising emp = null;
while (reader.Read())
{
emp = new Advertising();
emp.Id = Convert.ToInt32(reader.GetValue(0));
emp.SearchString = reader.GetValue(1).ToString();
emp.OstanID = Convert.ToInt32(reader.GetValue(2));
emp.AdsGroupID = Convert.ToInt32(reader.GetValue(3));
Advertising.Add(emp);
}
myConnection.Close();
return Advertising;
}
public Advertising Get(int id)
{
Advertising.Clear();
SqlDataReader reader = null;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Server=.;Database=AppServices;User ID=sa;Password=123;";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "SELECT * FROM tblAdvertising WHERE Id=" + id + "";
sqlCmd.Connection = myConnection;
myConnection.Open();
reader = sqlCmd.ExecuteReader();
Advertising emp = null;
while (reader.Read())
{
emp = new Advertising();
emp.Id = Convert.ToInt32(reader.GetValue(0));
emp.SearchString = reader.GetValue(1).ToString();
emp.OstanID = Convert.ToInt32(reader.GetValue(2));
emp.AdsGroupID = Convert.ToInt32(reader.GetValue(3));
Advertising.Add(emp);
}
myConnection.Close();
return Advertising.Find(p => p.Id == id);
}
public Advertising Add(Advertising item)
{
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Server=.;Database=AppServices;User ID=sa;Password=123;";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "INSERT INTO tblAdvertising (SearchString, OstanID, AdsGroupID) VALUES (#SearchString, #OstanID, #AdsGroupID)";
sqlCmd.Connection = myConnection;
sqlCmd.Parameters.AddWithValue("#SearchString", item.SearchString);
sqlCmd.Parameters.AddWithValue("#OstanID", item.OstanID);
sqlCmd.Parameters.AddWithValue("#AdsGroupID", item.AdsGroupID);
myConnection.Open();
int rowInserted = sqlCmd.ExecuteNonQuery();
// Get new record id
sqlCmd.CommandText = "SELECT TOP (1) Id FROM tblAdvertising ORDER BY Id DESC";
if (sqlCmd.ExecuteScalar() != DBNull.Value)
_nextId = (int)sqlCmd.ExecuteScalar();
////////////////////
myConnection.Close();
// old code
if (item == null)
{
throw new ArgumentNullException("item");
}
item.Id = _nextId;
Advertising.Add(item);
return item;
}
public void Remove(int id)
{
Advertising.RemoveAll(p => p.Id == id);
}
public bool Update(Advertising item)
{
if (item == null)
{
throw new ArgumentNullException("item");
}
int index = Advertising.FindIndex(p => p.Id == item.Id);
if (index == -1)
{
return false;
}
Advertising.RemoveAt(index);
Advertising.Add(item);
return true;
}
}
}
I have ASP.Net MVC 5 Web API project. I cant use asp.net web API 2 web service in android my web service is under mvc5, Then I have created mobile app in Eclipse Juno and i use Android sdk 21 below is my edited code
There are many issues.
It starts with what looks a little careless "SELECT * FROM tblAdvertising"
That is three sins against the rules of SQL.
First there is no table called tblAdvertising. There is one called dbo.tblAdvertising. So lacking the real name SQL assumes that you mean dbo, but that might be something else as well. This will dump your performance. Best always use fully qualified names.
The second issue is that you use * as items to select. I have been a long in SQL development and can tell from own experience how often tables are changed. The person doing so might not even be aware of your application so a simple add will cause your code to break. Always use fully qualified SQL column names as well.
The final issue with your SQL is that you use a command and yet poke in text strings, even those that are unprotected against SQL injection. What if someone adds this as string "'',0,0; truncate table tblAdvertising; --". You might be surprised how often, certainly in the past i could log in websites simply with some variation of "'' or 1=1 --". Best avoid unprotected strings that go to MSSQL or MySQL or any SQL for that matter. Also your SQLstring needs to be compiled taking a further performance hit. There is also no protection against wrong parameters or proper feedback if the result does not exist.
Besides you really do not want to select an entire table. There should be like a top 100 or you could implement some paging.
So the solution is that you use a proper stored procedure, check the parameter input and provide limited and properly formatted output.
Also your
INSERT INTO tblAdvertising (SearchString, OstanID, AdsGroupID) VALUES (#SearchString, #OstanID, #AdsGroupID)
can be much improved.
If you update or insert there is an output statement in SQL that is massive faster than querying the max number
create type dbo.IntTable as table(i int)
go
create proc dbo.AdvertisementInsert
#SearchString varchar
, #OstanID int
, #AdsGroupID int
, #NewID int = 0 output
as
set nocount on -- important to avoid second roundtrip over the network
declare #i as dbo.IntTable -- use predefined table variable
-- always check quality of input first
if #SearchString is null return 50001
-- also avoid rollback transaction since that is costly.
-- Better to ask first if this not already exist
if exists(select 42 from dbo.tblAdvertising where SearchString = #SearchString) return 50002
INSERT INTO tblAdvertising (SearchString, OstanID, AdsGroupID)
output inserted.Id into #i -- catch new id directly into table variable
VALUES (#SearchString, #OstanID, #AdsGroupID)
-- report the result
select #NewID = i from #i -- convert table variable to single int
go
So now your proc can be called just using the parameters and will tell you back either 0 .. in which case the result code will tell you why it failed, or some other number matching the new identity
Enjoy

Lambda expression for getting a table row and update the row in database

I am trying to update my DB table and from my model I am getting the id
public void Update(Abc model)
{
//Database Table Instance
Abc a=new Abc();
//Trying to update the column where id =id
try
{
a.id = model.Asset.id;
a.column = "R";
db.Entry(a).State = EntityState.Modified;
db.SaveChanges();
}
catch (Exception e) { }
}
It set the column to R bt sets Nulls for all other columns because I am not getting values for other columns from model. One way is to set the hidden values in model and send the model but the table has about 30 columns. so I want to get the table row from database where id=id and the only updatte the column in that row in my function in repository .....
In order to achieve this first you need to get the actual object from your db context and then change the desired property and save it to in database like below:
try
{
Abc a = db.Abcs.SingleOrDefault(a => a.id == model.Asset.id);
a.column = "R";
db.SaveChanges();
}
catch (Exception e) { }
This will fix your concern.

db4o: how can we get the data for only one object?

How can DB4o users get back the data for only one object?
(This is akin to getting the data for only one row of a traditional relational database table.)
With DB4o, I only know how to get the data back for a class of objects but not simply one unique object instance.
just query objects and get first item out of the result (the same like in relational database)
to get it by Guid ID:
using (IObjectContainer session = this.GetNewSession())
{
Dummy result = (from Dummy item in session
where item.Id == Guid.Parse("....")
select item).FirstOrDefault()
}
the result will be either null if item doesn't exist or the object found
other option is to get it directly by internal ID such as (or even UUID):
long id = ....;
using (IObjectContainer session = this.GetNewSession())
{
Dummy result = (Dummy)session.Ext().GetByID(id);
}
I have answered my own question (I believe):
Solution #1:
public List<Object> getListOfObjects(final Object o){
List<Object> result = db.query(new Predicate<Object>(){
#Override
public boolean match (Object arg0){
if(arg0.equals(o)){
return true;
}
else{
return false;
}
});
return result;
}
Solution #2:
public ObjectSet<Class<?>> getListOfObjects(Object o){
Query q = db.query();
q.constrain(o);
ObjectSet<Class<?>> set = q.execute();
return set;
}
Maybe someone knows if one of these solutions is better than the other, or whatever.

Asp.Net MVC 3 - Linq To Entities - PK with Null doesn't get inserted into the db (don't want null :))

I'm using the latest Asp.Net MVC version.
For some reason, when my POST (Action Create) in my controller gets hit.
I can't seem to be able to add it to the entityset.
What i have is,
1) My EntityModel (*.edmx file)
2) Controller which references the entity:
private db.DataContainer _db = new db.DataContainer();
3) My method (i'm using Guid as pk):
[HttpPost]
public ActionResult Create(Client client)
{
try
{
client.Id = Guid.NewGuid();
/* method 2
Client cl = new Client();
cl.Id = Guid.NewGuid();
cl.email = client.email;
cl.Adres = client.Adres;
cl.companyName = client.companyName;
cl.fax = client.fax;
cl.phone = client.phone;
*/
// client.Id = Guid.NewGuid();
_db.ClientSet.AddObject(client);
_db.SaveChanges();
return RedirectToAction("Index");
}
catch (Exception ex)
{
var ex_message = ex.Message;
var ex_data = ex.Data;
var ex_ix = ex.InnerException;
return View();
}
}
4) Following is my InnerException:
[System.Data.SqlClient.SqlException] = {"Cannot insert the value NULL into column 'Id', table 'lst.dbo.ClientSet'; column does not allow nulls. INSERT fails.\r\nThe statement has been terminated."}
Both doesn't seem to work :(
GUIDs are not supported as primary keys in the Entity Framework. You will need to modify your save method to generate a new GUID for your added objects http://msdn.microsoft.com/en-us/library/dd283139.aspx
It seems that changing my "saveCommand" has given my a temporarily solution:
I chaned:
_db.SaveChanges()
To
_db.SaveChanges(System.Data.Objects.SaveOptions.None);

Resources