WCF Service and Windows Application Client. why client receives null - winforms

I have mapped the service with a linq to Sql classes and I am using wcf library for vs 2019 and in client a win form app.
I am trying sending the class created for linq to sql the next way
public List<Trades> GetAllTradings()
{
context = new DCStockTradingDataContext();
List<Trades> tradings = (from t in context.Trades
select t).ToList();
return tradings;
}
and the client
private void btnRun_Click(object sender, EventArgs e)
{
Service1Client client = new Service1Client();
var trades = client.GetAllTradings();
dgViewStocks.DataSource = trades;
//string ret = client.GetData("Hello");
//Console.WriteLine(ret);
}
I din´t know what is happening and I don´t know what is wrong
The service
and the client receives all null
I would appreciate any help about this and thank you in advance

If you get null response in WCF client, some advices:
try to call the service in SoapUi with Validation of request and response turned on. It may be useful in detecting problems.
debug Reference.cs file to see more closely what is going on
use MessageInspector to see what is received in AfterReceiveReply method
examine namespaces attentively, response often cannot be deserialized because of the difference in namespaces that are in Reference.cs and in real service

Thanks for your response and everything if this I did.
I found how I have to work with linq to sql classes and wcf. We need to take into account that you need to convert the List of linq classes to List<string. What I did
enter code here
public List<string[]> GetAllStocks()
{
context = new DCStockTradingDataContext();
System.Data.Linq.Table<Stocks> stocks = context.GetTable<Stocks>();
var allStock = (from st in stocks
select new
{
stockId = (string) st.CodeID,
currency = (char) st.Currency,
stName = st.Name,
price = (decimal) st.Price,
volument = (decimal) st.Volumen
}).ToList();
List<string[]> listRetruned = new List<string[]>();
foreach (var tr in allStock)
{
string[] t = new string[5];
t[0] = tr.stockId;
t[1] = tr.currency.ToString();
t[2] = tr.stName;
t[3] = tr.price.ToString();
t[4] = tr.volument.ToString();
listRetruned.Add(t);
}
return listRetruned;
}
and the client
I have created a model class with the expected data
public class TradingModel
{
public string TradeID { get; set; }
public string StockId { get; set; }
public decimal Bid { get; set; }
public int BidQty { get; set; }
public decimal Ask{get;set;}
public int AskQty { get; set; }
public decimal Last { get; set; }
}
and finally the method
List<TradingModel> models = new List<TradingModel>();
for(int i = 0; i < trades.Length; i++)
{
TradingModel model = new TradingModel()
{
Ask = Convert.ToDecimal(trades[i][0]),
Bid = Convert.ToDecimal(trades[i][1]),
BidQty = Convert.ToInt32(trades[i][2]),
AskQty = Convert.ToInt32(trades[i][3]),
Last = Convert.ToDecimal(trades[i][4]),
StockId = trades[i][5],
TradeID = trades[i][6],
};
models.Add(model);
}
dgViewStocks.DataSource = models;
I am not sure if this is the best way to jump to next step, but it worked for me. If someone is looking for this info as I did, wasting several days chasing the solution, I leave what I did.
There is off course changing the service and generate the proxy again

Related

Dapper control dates

This question is meant to bring some light around control date times using Dapper.
These controls are used to audit the information in a data storage and figure out when a particular row has been created / updated. I couldn't manage to find any information on GitHub's project, either here in StackOverflow, so I would like this post to become a central source of truth to help others or even to turn into a future extension of the library.
Any answer, resource or best practice will be appreciated.
I've ran into a case where I was working with a database that was consumed by both Rails and Dapper. Rails was managing created_at and updated_at, not the database. So with the .net application I had to implement a solution that managed these and provided the ability to add additional business logic at these layers such as events.
I've included a basic example of how I handled this with a wrapper around Dapper Simple Crud for inserts and updates. This example does not include exposing the other critical methods from dapper and simplecrud such as Query, GET, Delete, etc. You will need to expose those at your discresion.
For safety ensure that you decorate your models created_at property with the attribute [Dapper.IgnoreUpdate]
[Table("examples")]
public partial class example
{
[Key]
public virtual int id { get; set; }
[Required(AllowEmptyStrings = false)]
[StringLength(36)]
public virtual string name { get; set; }
[Dapper.IgnoreUpdate]
public virtual DateTime created_at { get; set; }
public virtual DateTime updated_at { get; set; }
}
public class ExampleRepository : IExampleRepository
{
private readonly IYourDapperWrapper db;
public PartnerRepository(IYourDapperWrapper yourDapperWrapper){
if (yourDapperWrapper == null) throw new ArgumentNullException(nameof(yourDapperWrapper));
db = yourDapperWrapper;
}
public void Update(example exampleObj)
{
db.Update(exampleObj);
}
public example Create(example exampleObj)
{
var result = db.Insert(exampleObj);
if (result.HasValue) exampleObj.id = result.value;
return exampleObj;
}
}
public class YourDapperWrapper : IYourDapperWrapper
{
private IDbConnectionFactory db;
public YourDapperWrapper(IDbConnectionFactory dbConnectionFactory){
if (dbConnectionFactory == null) throw new ArgumentNullException(nameof(dbConnectionFactory));
db = dbConnectionFactory;
}
public int Insert(object model, IDbTransaction transaction = null, int? commandTimeout = null)
{
DateUpdate(model, true);
var results = Db.NewConnection().Insert(model, transaction, commandTimeout);
if (!results.HasValue || results == 0) throw new DataException("Failed to insert object.");
return results;
}
public int Update(object model, IDbTransaction transaction = null, int? commandTimeout = null)
{
DateUpdate(model, false);
var results = Db.NewConnection().Update(model, transaction, commandTimeout);
if (!results.HasValue || results == 0) throw new DataException("Failed to update object.");
return results;
}
private void DateUpdate(object model, bool isInsert)
{
model.GetType().GetProperty("updated_at")?.SetValue(model, DateTime.UtcNow, null);
if (isInsert) model.GetType().GetProperty("created_at")?.SetValue(model, DateTime.UtcNow, null);
}
}

creating items collection in a custom control

I have a Custom control inheriting from Control class in my WinForm. My control contains multiple panels and other UIElements.
This is what my control is supposed to look like
There's a database panel,
database panel contains a single checkbox only.
and there's a Server panel,
server panel contains many database panels and a single label; the header label.
And finally there's the container panel that contains all my Server panels.
I found this Item Collection option for a User Control but I couldn't really understand the accepted answer on it. If someone could help explain it better that would be great.
Also, if someone could just put some links for creating advanced custom controls. I've been reading all day about it and I still can't make any sense of it all. Is there a step-by-step guide for advanced custom controls?
[Edit]
Basically what I need is to create a custom collection within my custom control. Currently my control is built as Winform Control Library which I build and then I use in my main program later.
So in my main program, I can just drag and drop the component on my form and use it.
By default, the custom control will load with one Server that contains one database.
What I want is to be able to add/remove other databases/servers to it if I need to, in my MAIN program
I'm having trouble explaining exactly what I need because I simply do not understand how the whole custom control/items collection thing works really, and i'm sorry for that. I would really appreciate some links that explains this stuff clearly
here's my code for this control:
This code only creates my default control, but I am UNABLE to add to it. The collection property appears in my property windows but when I add items to it and click okay nothing happens.
public class Database : System.Windows.Forms.Panel
{
public CheckBox _ckbDatabase;
public Database()
{
_ckbDatabase = new CheckBox();
this.BackColor = _pnlDatabaseBackColor;
this.Size = _pnlDatabaseSize;
this.AutoSize = false;
this.Height = 40;
this.Width = 200;
this.Location = _pnlDatabaseLocation;
_ckbDatabase.Top = 10;
_ckbDatabase.Left = 15;
_ckbDatabase.TextAlign = _ckbdbTextAlignment;
_ckbDatabase.Font = _ckbdbFont;
_ckbDatabase.ForeColor = Color.White;
this.Controls.Add(_ckbDatabase);
}
#Propterties
}
public class Server : System.Windows.Forms.Panel
{
private Label _lblserver;
private Database database;
public Server()
{
_lblserver = new Label();
database = new Database();
this.BackColor = _pnlServerBackColor;
this.Size = _pnlServerSize;
this.AutoSize = false;
_lblserver.Dock = _lblserverDock;
_lblserver.Font = _lblsrvFont;
_lblserver.BackColor = _lblServerBackColor;
_lblserver.AutoSize = false;
_lblserver.Text = SRV;
database.Top = 35;
database._ckbDatabase.Text = DB;
this.Controls.Add(_lblserver);
this.Controls.Add(database);
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public DatabaseCollection DatabaseCollection { get; set; }
#Propterties
}
public class ServersCollection : CollectionBase
{
public Server this[int index]
{
get { return (Server)List[index]; }
}
public void Add(Server server)
{
List.Add(server);
}
public void Remove(Server server)
{
List.Remove(server);
}
}
How about something simple like this:
public class Server {
public string Name { get; set; }
public List<Database> Databases { get; set; }
public Server() {
Databases = new List<Database>();
}
}
public class Database {
public string Name { get; set; }
public bool Enabled { get; set; }
}
Then you can just add it like this:
List<Server> servers = new List<Server>();
Server serverA = new Server { Name = "Server A" };
serverA.Databases.Add(new Database { Name = "Database 1", Enabled = true });
serverA.Databases.Add(new Database { Name = "Database 2", Enabled = false });
Server serverB = new Server { Name = "Server B" };
serverB.Databases.Add(new Database { Name = "Database 1", Enabled = false });
serverB.Databases.Add(new Database { Name = "Database 2", Enabled = false });
servers.Add(serverA);
servers.Add(serverB);
When you link to the Item Collection part it seemed like you wanted to be able to add servers and databases in design mode but then you mention you want to do it by code? If this is not what you want you need to give us more information.
Looks to me like you are mostly there. First off, here's a more complete collection class:
public class ServersCollection : IEnumerable<Server>
{
private List<Server> _servers = new List<Server>();
public Server this[int index]
{
get { return _servers[index]; }
}
public IEnumerator<Server> GetEnumerator()
{
foreach (var server in _servers)
yield return server;
}
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public void Add(Server server)
{
_servers.Add(server);
}
public void Remove(Server server)
{
//You might consider a deliberate loop to evaluate a proper match
//Don't forget to Dispose() it first!
_servers.Remove(server);
}
public void Clear()
{
for (Int32 i = _servers.Count - 1; i >= 0; i--)
_servers[i].Dispose();
_servers.Clear();
}
}
Add an instance of the ServersCollection class to the container control, the one at the top level that holds server panels:
private ServersCollection _servers = new ServersCollection();
public ServersCollection Servers { get { return _servers; } }
Use that as a way for it to add Server controls to its own collection of controls.
Do a similar thing with the DatabaseCollection in the Server class, again so that it can add Database panels to its controls collection.
Then, wherever you have an instance of a control, you will also have access to the collection of what it holds:
myControl.Servers
//-or-
myServer.Databases
...allowing you to add/remove, as such:
myControl.Servers.Add(new Server());
//-or-
myServer.Databases.Add(new Database());
Points of emphasis
Your classes are controls, but they also own other controls. Proper use of the Dispose pattern will be crucial or you'll have memory issues throughout.
I would remove these lines, they don't matter unless you intend to add servers/DBs at form design time (i.e. fixed entries or defaults):
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public DatabaseCollection DatabaseCollection { get; set; }
Finally, you could (should!) take that collection class further, with overloads for Add() and Remove() that do a better job of deciding when/how/what to do based on more than an instance, e.g. by name? You could also add another indexer to fetch by name, for instance, instead of just index (which you might not readily know).

Why is creating a MSSQL(Express) database with Entity Framework so slow?

We are developing a WPF application which can manage multiple clients. For each client we need a separate database (within the same SQL Server instance). So we need a „create database“ more than once. All individual client-databases will have all the same database structure.
We use Entity Framework Version 6.1.3, code-first and a local installation of SQL Server 2014 Express. In our „real“ business-application a new database with about 60 tables is created properly, but the performance is not so good.
Trying to isolate the problem I wrote a small sample program which creates 5 databases in a loop, 1 table per database. On my Dev-PC (Windows 10, i7-6700 3.40GHz, 16 GB RAM) the executiontime for those 5 databases is about 1 minute (11-12 secs for each database). When I debug the application, I see that there is a long wait on the line
dbContext.Database.CreateIfNotExists();
In SQL Server Profiler I see that it takes about 10 seconds per loop until the first entry arrives.
Any idea's where the time is lost? Or other suggestions for creating many databases (> 20) with the same DbContext in Entity Framework?
Here the source-code of my sample application:.
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System;
namespace TestEnityFramework01.Model
{
[Table("Table01")]
public class Table01 {
[Key]
[Column("ID", Order = 0, TypeName = "int")]
public int ID { get; set; }
[Column("Number01", TypeName = "int")]
public int Number01 { get; set; }
[Column("Date01")]
public DateTime? Date01 { get; set; }
[StringLength(50)]
[Column("Text01", TypeName = "nvarchar")]
public string Text01 { get; set; }
[Column("Amount01")]
public decimal Amount01 { get; set; }
[Column("Doule01")]
public double Doule01 { get; set; }
[Column("Bool01")]
public bool Bool01 { get; set; }
}
}
And the context:
using TestEnityFramework01.Model;
using System.Data.Entity;
namespace TestEnityFramework01.Context
{
class ContextA : DbContext
{
public DbSet<Table01> Tabel01 { get; set; }
public ContextA()
: base("ContextA")
{
// Don't create database automatically
Database.SetInitializer<ContextA>(null);
}
public ContextA(string pConnectionString)
: base(pConnectionString)
{
// Don't create database automatically
Database.SetInitializer<ContextA>(null);
this.Configuration.AutoDetectChangesEnabled = false;
this.Configuration.LazyLoadingEnabled = false;
this.Configuration.ValidateOnSaveEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
}
}
}
The test program produces in a loop five databases:
private void button_Click(object sender, RoutedEventArgs e)
{
int _randomNumber = 0;
for (int i = 1; i <= 5; i++)
{
// create random number between 1 and 100'000
_randomNumber = new Random().Next(1, 100000);
// concat the random number to the database name
string _databaseName = "DatabaseCustomer" + _randomNumber.ToString();
// the connection-string look like this:
// "Data Source=MyPC\SQLEXPRESS;Initial Catalog=MyDatabaseName;User ID=MyUser;Password=MyPassword;Integrated Security=False;MultipleActiveResultSets=True;"
string _connectionString = GetConnectionString(_databaseName);
using (var dbContext = new ContextA(_connectionString))
{
// create the database
dbContext.Database.CreateIfNotExists();
}
}
}
**** UPDATE 16.06.2016****
When I switch the DB connection from SQL-Server 2014 Express to „SQL Server Compact Edition“, the creationtime for all 5 databases is about 1 or 2 seconds. Could it be that i use a wrong connectionstring to connect with the sql-server or my SQL-Server 2014 Express is not configured properly?
This is because the code first Approach creates a new database and establishes connection with it.
I Think you should use sql query for Creating Database.
If You Want I can help you how will you do it with better UI and Functionality design
Please reply for my answer.

Solr C# client that convert query result to object

I am really new to solr.
I am wondering if there is C# client that allow me to convert solr query result to C# object?
I also have the solr schema xml but not sure how to convert it to C# class? Do i need to parse the xml?
There are many different Solr client implmentations for C#.
I have tried couple different ones, but only SolrNet worked with the current version.
(SolrNet version: SolrNet-0.4.0.2002.zip (843.53Kb), Solr version: 4.7.1)
First I have tried to use the NuGet package, but it turned out that it is outdated (was using deprecated API), get the newest version from here:
Solr Net - Master
Build the dlls and use them in your project.
You can find a nice tutorial here:
SolrNet tutorial
The only problem here is that these calls are now deprecated. Instead of Add method you should be calling the actually supported Commands. Add and the other derprecated methods already worked well but I don't think that you should rely on deprecetad calls.
Instead of these you can use the different Command classes representing the different Solr operations.
Example:
using Microsoft.Practices.ServiceLocation;
using SolrNet;
using SolrNet.Attributes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication1
{
class Program
{
class Product
{
[SolrUniqueKey("id")]
public string Id { get; set; }
[SolrField("manu")]
public string Manufacturer { get; set; }
[SolrField("cat")]
public ICollection<string> Categories { get; set; }
[SolrField("price")]
public decimal Price { get; set; }
[SolrField("inStock")]
public bool InStock { get; set; }
}
static void Main(string[] args)
{
Startup.Init<Product>("http://localhost:8983/solr");
var p = new Product
{
Id = "SP2514M",
Manufacturer = "Samsung Electronics Co. Ltd.",
Categories = new[] {
"electronics",
"hard drive",
},
Price = 92,
InStock = true,
};
var solr = ServiceLocator.Current.GetInstance<ISolrConnection>();
Dictionary<Product, double?> dict = new Dictionary<Product,double?>();
dict.Add(p, 0);
Console.WriteLine("-- Add products --");
AddProducts(solr, dict);
Console.WriteLine("-- Commit changes --");
CommitChanges(solr);
Console.WriteLine("--Query all documents --");
QueryAll();
Console.WriteLine("-- Delete all documents --");
DeleteAll(solr);
Console.WriteLine("-- Commit changes --");
CommitChanges(solr);
Console.WriteLine("--Query all documents --");
QueryAll();
Console.ReadKey();
}
private static void DeleteAll(ISolrConnection solr)
{
SolrNet.DeleteParameters del = new DeleteParameters();
SolrNet.Impl.FieldSerializers.DefaultFieldSerializer deffield = new SolrNet.Impl.FieldSerializers.DefaultFieldSerializer();
SolrNet.Impl.QuerySerializers.DefaultQuerySerializer defquery = new SolrNet.Impl.QuerySerializers.DefaultQuerySerializer(deffield);
SolrNet.Commands.Parameters.DeleteByIdAndOrQueryParam delpar = new SolrNet.Commands.Parameters.DeleteByIdAndOrQueryParam(Enumerable.Empty<string>(), SolrNet.SolrQuery.All, defquery);
var delete = new SolrNet.Commands.DeleteCommand(delpar, del);
string res = delete.Execute(solr);
System.Diagnostics.Trace.WriteLine(res);
}
private static void CommitChanges(ISolrConnection solr)
{
SolrNet.Commands.CommitCommand commit = new SolrNet.Commands.CommitCommand();
string res = commit.Execute(solr);
System.Diagnostics.Trace.WriteLine(res);
}
private static void AddProducts(ISolrConnection solr, Dictionary<Product, double?> dict)
{
AddParameters par = new AddParameters();
ISolrDocumentSerializer<Product> ser = ServiceLocator.Current.GetInstance<ISolrDocumentSerializer<Product>>();
SolrNet.Commands.AddCommand<Product> addProduct = new SolrNet.Commands.AddCommand<Product>(dict, ser, par);
string res = addProduct.Execute(solr);
System.Diagnostics.Trace.WriteLine(res);
}
private static void QueryAll()
{
// Query all documents
var query = SolrNet.SolrQuery.All;
var operations = ServiceLocator.Current.GetInstance<ISolrOperations<Product>>();
var Products = operations.Query(query);
int i = 0;
foreach (var product in Products)
{
i++;
Console.WriteLine("{0}:\t {1} \t{2} \t{3}", i, product.Id, product.Manufacturer, product.Price);
}
if(i == 0)
{
Console.WriteLine(" = no documents =");
}
}
}
}
I am very new to Solr too so my code may contain some flaws. Please help me spot them. Thank you.
See QueryAll method for querying and using the resulting objects.

.Net WCF RIA Services parameterized NameValue method crashing

I added a RIA Domain Service method to return a simple NameValuePair of two properties from a table (and filtered on a key value).
It compiles fine, but blows up every time without giving a useful error.
What am I missing? (probably something really obvious)
e.g.:
public IQueryable<NameValuePair> GetNameValues(int keyId)
{
// NOTE: I can breakpoint here and the correct keyId is passed
// it blows up on returning from this method
return from p in this.ObjectContext.NameTable
where p.KeyId == keyId
select new NameValuePair(p.NameValue, p.NameType);
}
Simple NameValuePair Code:
public class NameValuePair
{
[Key]
public string Name { get; set; }
public string Value { get; set; }
public NameValuePair()
{
}
public NameValuePair( string name, string value)
{
this.Name = name;
this.Value = value;
}
}
Update:
I tried returning a query on a static list of NameValuePair objects and that works fine (but is not useful).
I tried this here and got the error: base {System.SystemException} = {"Only parameterless constructors and initializers are supported in LINQ to Entities."}
So you have to change it to create the object first, then pass the property values:
public IQueryable<NameValuePair> GetNameValues(int keyId)
{
return from p in this.ObjectContext.NameTable
where p.KeyId == keyId
select new NameValuePair {Name = p.NameValue, Value = p.NameType};
}

Resources