Create SQL linked server with a .net class (C#) - c#

I have a program where I used "SQLConnectionStringBuilder" and it was quite easy and handy to do use.
Now, I would like to use the linked server class from Microsoft in order to create a linked server easily. However, I am a bit stuck trying to understand the documentation because it has no examples.
https://learn.microsoft.com/en-us/dotnet/api/microsoft.sqlserver.management.smo.linkedserver?view=sql-smo-preview
So far I thought it would be something like below:
LinkedServer linkedServer = new LinkedServer();
CreateLinkedServer(string server, string database)
{
linkedServer.Name = "NewLinkedServer";
linkedServer.DataSource = server;
linkedServer.Catalog = database;
}
At the moment it gives the following error:
you must set Parent property.
I believe I am missing the authentication mode (and probably something else) to use in order to connect but I've only have seen in the list the "LinkedServerLogins" property which I am not sure how to use.
Can somebody help me?
Thanks in advance

Related

Getting list of properties of a DataType from current page

Good evening!
I am currently working on the backend of my application and I need to get a list of all properties of a certain datatype but only the ones in the current page.
listFiltersCms = _umbraco.ContentAtRoot().SelectMany(c => c.Descendants<DataFilters>()).ToList();
This line above gathers all the filters from all the pages, but I want the filters from a specific page (can be currentPage).
I have tried something like this:
var listFiltersCms = _umbraco.AssignedContentItem.SelectMany(c => c.Descendants<DataFilter>()).ToList();
But without any luck :( Any ideas?
Not entirely sure what you mean by "the backend of my application" - are you inside Umbraco or on a public website?
I ask because there is a fairly straightforward way of getting all info on a specific datatype, but it is not really meant to be used on public facing websites. It can be, but it might be taxing on the system as I believe it queries the database directly, which is not ideal.
Anyway, you might want to take a look at the DataTypeService:
https://our.umbraco.com/Documentation/Reference/Management/Services/DataTypeService/Index-v8
And here you can see what options you have for using it (not very explanatory, but I spot a few methods you could probably look into):
https://our.umbraco.com/apidocs/v8/csharp/api/Umbraco.Core.Services.IDataTypeService.html
If you decide to use the service in a scenario where there will be a lot of requests, maybe consider caching the output to spare the database.
The way I solved this issue was by getting the page in the correct model. In my case all I had to do was:
(_umbraco.AssignedContentItem as PageModel).FilterCustomMeasures;

Cannot assign to foreign keys in Lightswitch - Property or indexer cannot be assigned to -- it is read only

I looked at other similar questions, but I cannot figure this out on my own. I am currently using Lightswitch 12.0.3 Update 4 version of Lightswitch and I previous versions of Lightswitch I could do these kind of things with ease... So I don't understand what changed and why I am not able to do this anymore.
I get an error:
Property or indexer 'LightSwitchApplication.Report.Customer' cannot be assigned to -- it is read only
Where Report is my screen and Customer is my table. So in the code behind (of the screen) I am trying to do this:
partial void Report_InitializeDataWorkspace(List<IDataService> saveChangesTo)
{
if (this.CustomerId.HasValue)
{
this.Customer = this.DataWorkspace.ApplicationData.Customers.Where(w => w.Id == this.CustomerId.Value).Single();
}
}
And in this case, CustomerId is a local int property added to my screen.
Now the error is that this.Customer cannot be assigned to, because it is read-only.
What am I missing?
Also, I am getting the same error in another place:
Property or indexer 'LightSwitchApplication.Report.NewProduct' cannot be assigned to -- it is read only
partial void CreateNewProduct_Execute()
{
this.NewProduct = this.DataWorkspace.ApplicationData.Products.AddNew();
this.OpenModalWindow("NewProduct");
}
I suspect the issues you're encountering relate to the many changes between the early 2011 beta versions and the RTM release.
Whilst I'm a little bit rusty on the Silverlight side of things (having focused on the HTML 5 LightSwitch route in recent years) I'll try and provide some pointers which may help.
As regards your Report_InitializeDataWorkspace code (which I'm guessing is intended to default the this.Customer values based upon a passed parameter) you should be able to tackle this as follows: -
if (this.CustomerId.HasValue)
{
var c = this.DataWorkspace.ApplicationData.Customers.Where(w => w.Id == this.CustomerId.Value).Single();
this.Customer.Name = c.Name;
this.Customer.AddressLine1 = c.AddressLine1;
}
If this isn't your intention, please can you provide a little more background regarding what you're trying to implement.
Regarding the CreateNewProduct code you should be able to implement something along the following lines: -
partial void CreateNewProduct_Execute()
{
Product newProduct = this.DataWorkspace.ApplicationData.Products.AddNew();
this.Products.SelectedItem = newProduct;
this.OpenModalWindow("NewProduct");
}
Again, if I've misunderstood your intentions, please can you provide more background.
The following article may also help with this area (though it only covers the vb approach and not c# code): -
LightSwitch Team Blog - Creating a Custom Add or Edit Dialog (Sheel Shah)
Whilst the article is circa the 2011 edition, it should still be reasonably relevant to the 2013 update 4 version you're using.
without seeing the declaration of 'Customer' and 'NewProduct', I can only guess that you may have declared it as a Property with a Getter only - no Setter.
If this is not the case, could you show more code that demonstrates what is failing.
I solved the "problem" - It was my fault and failure to understand the difference between a data item as Query of type Customer and data item as Local Property of type Customer.
So in other words, I added both Customer and Product as local screen members instead of queries and now my code works as intended.

Get data from WCF

I'm so confused. Although I have a fair background in C#, this is my first exposure to WCF.
I have a C# desktop application that does a few functions such as getting data from a local xml file, and other various functions, which I don't need to explain here because they don't relate to this question. Now I need to use a URL for a WCF Service to get some other data to use in my application.
The more I read about WCF online and go through the tutorials the more confused I get. That's why I'm requesting a really simple, clear, straight-forward answer to my questions here. I'm not looking for anything fancy or advanced like setting up a WCF Service Library or WCF Service Application. I'm simply a beginner to WCF who wants to use a WCF service URL in my existing C# desktop application to get some data. The WCF service was provided to me by someone else, and is properly working. Please keep in mind when answering this question that I am new to WCF, so a beginner level answer to this topic is best.
This is what I've don so far:
Created a C# Windows Forms Application that properly builds and runs. The application has a few custom classes, a local xml file for data retrieval, and some event handlers for button clicks and such in the Form1 class.
I added the WCF service reference to my project (i.e., right-click project > Add Service Reference > paste in url > Go > Ok.
Added the System.Data.Services.Client reference to my project. Although I don't know if this is even needed.
In my Form1 class where the event handlers are, I added the following using directives: using MyProject.theService and using System.Data.Services.Client.
Added these global variables at the beginning of the Form1 class:
private Uri svcUri = new Uri("http://www ... service.svc");
private ServiceClient context;
In the Form1 class, in a button event, I have the following code:
-
private void btnWebService_Click(object sender, EventArgs e)
{
ServiceClient client = new ServiceClient();
Student s = new Student();
// this is implemented as follows in the student class: public Fee[] Fees { get; set; }
Fee f = new Fee();
// need some logic here to get the data using the client object
client.Close();
}
There is a method of the client object called GetFees (client.GetFees()) and I'm assuming it is the most logical choice to use this method to get the data I need (which is the fees associated with the students). Visual Studio gives this description of the method:
theService.Student[] ServiceClient.GetFees(theService.Student[] students)
What I'd like is when I click the button and fire the btnWebService_Click event, I call the service, retrieve the needed data, store it in the appropriate object, and have the data to use however I need.
My question are:
On step 6, am I moving the right direction?
Have I missed any steps in order to made the WCF call work?
The GetFees() method is confusing me. How do I write the correct C# code to use it without errors?
I've tried writing this line of code in the event handler:
f = client.GetFees(s.Fees[0]);
But I get the following errors in Visual Studio:
The best overloaded method match for 'MyProject.theService.ServiceClient.GetFees(MyProject.theService.Student[])' has some invalid arguments
Argument 1: cannot convert from 'MyProject.Fee' to 'MyProject.theService.Student[]'
What is am I doing wrong here? Or is this line even close to anything I need?
I've purposefully excluded the full url of the WCF service from this question. If it helps to have it to properly answer this question please let me know and I will give it to you. Also, there is a wsdl url. Let me know if having it will help you answer my questions.
Thank you in advance for reading all this. I welcome and appreciate any kind of help you can provide.
------------------------- EDIT -------------------------
Based on some of the help I've received I'm getting very close to a solution. But I still have one issue.
This code compiles and runs:
private void btnWebService_Click(object sender, EventArgs e)
{
ServiceClient client = new ServiceClient();
theService.Student s = new theService.Student();
theService.Student[] stds = new theService.Student[30];
stds[0] = s;
var ret = client.GetFees(stds);
client.Close();
}
However, I get the following error from Visual Studio:
Invalid StudentID(=0). StudentID must be greater than 0.
This error occurs because the values in stds[0] are null.
In a different part of my program, I have a LINQ query that grabs the student data from an xml file and stores it in a List<Student> students object.
So looking at the code above, my next step would be to assign the values from students to stds[0]. The problem I cannot figure out is some issue with casting or conversion. How do I assign student objects from List to a theService.Student[] object so that I can provide the service some data to look up?
I've tried doing this:
stds[0] = (theService.Student)students[0];
But of course I get this error:
Cannot implicitly convert type 'MyProject.Student' to 'MyProject.theService.Student'
I know this might seem really simple and obvious to some, but I cannot figure it out. I can't find the answer on Google. Someone please help.
You have your local information stored in an object called Student, and the service expects an object called Student but they are not the same thing.
I recommend creating either:
a) creating an extension method on YOUR student object to convert it to a service student object
b) creating an explicit conversion for your student object into a the service student object
but, the long way will be to do something like:
theService.Student s = new theService.Student();
s.Name = students[0].Name; //these are example fields
s.Id = students[0].Id; //these are example fields
var ret = client.GetFees(new theService.Student[] { s });
You're on the right track, you're just not calling the service as expected. The service expects you to pass in an array of Student objects, and it will return an array of Student objects.
theService.Student[] ServiceClient.GetFees(theService.Student[] students)
Try something like
var stds = new Student[];
stds[0] = s; // the Student you set up
var ret = client.GetFees( stds ); // ret is an array of Student
f = ret[0]; since you only passed a single student in, the 1st item in the return array should be your student with fees
Now, look at f.Fees for your data.
You can shorten this code quite a bit; I wanted to show discrete steps.

Entity Set Name Changing Randomly

I have a local and development environment, each very similar to each other (OS differences aside). They both run the same project which is making use of the Entity Framework. I use LINQpad quite a bit to interrogate data on both environments -- but where required I have access to SQL etc. etc.
So, this is all started with a very strange occurance. Within my business logic layer, I make a call to get a list of Contacts and then marshall that list into a custom type. The custom-type calls for an Initial index based on the name of each of the contacts.
For reference, this is the code that performs the marshalling:-
private static IEnumerable<AlphabetisedContact> _getGroupedContacts(int clientid)
{
return _getLiteContacts(clientid).GroupBy(c => c.Name[0]).Select(
g => new AlphabetisedContact { Initial = g.Key, Contacts = g.ToList() }).OrderBy(g => g.Initial);
}
So, this all seems to work fine. Except, it never returns any Contact with the first initial of a. I decided to try and debug this and using LINQpad found a weirdness. Whether this has anything to do with my code not returning a contacts I don't know (??), but this was the weirdness I found:-
Local Machine:-
Development Machine:-
For the less eagle-eyed of you, the Entity Set Name returned by EF, seems to be different. With the development machine, they're returned with underscores between words -- which is not how the EDMX was setup. For example, it is Name on local, Contact_name on dev. Again, this may have absolutely nothing to do with why I can't get a contacts. I don't get errors on the dev box, contacts are returned etc. etc. but I can't get a contacts.
Can anyone offer some assistance/advice/guidance on how to fix this? It's become a case of "wood-for-the-trees" now...
Help appreciated.
Turns out this was a catastrophic boo-boo on my part. Please see answer to this on this SO:
Why Won't This LINQ Return A Particular Initial?
Thanks to all who took the time to take a peek - and at least a stab at answer.
;)

Coding to make a SQL table from an InfoPath 2003 form without knowing the fields in advance

Using: InfoPath 2003 (and its XML), Microsoft SQL Server 2005, Visual Studio 2005, C# (to make a web service)
I've been trying to find something that does this already, and either my Google skills are failing or it's not actually possible, because I can't believe this hasn't already been needed by someone.
I am attempting to make a web service that takes an InfoPath form, gets the list of all the fields from the form (and their associated expected data types if the user bothered with validation), and creates a table in a SQL database with the same fields and expected types (probably using varchar as a default type where validation wasn't used). I can't just list the fields ahead of time, because in theory, managers and engineers will be making new forms for all sorts of purposes and I need to avoid confusing them or giving them direct access to the server.
I've never done anything of this sort before, nor have I used XML (or C#, for that matter). Before I drive myself crazy trying to make everything work, I need to know: is this possible? I know XML documents are basically made of user-defined tags, and I don't know if there's any way to distinguish form fields from any other tags associated with rendering the document properly. I also don't know if there are methods available for getting the expected data types. If this stuff is possible, any guidance in how would be appreciated.
Update
Judging from an InfoPath form at the XML level, it seems that all of the fields are contained in the <my:myFields> tag. It also contains the <xd:SchemaInfo> tag, so now I've got to figure out how to access all of the fields while ignoring that one.
I still don't know if I'm trying to do something that's weird, impossible for another reason, or bad practice, so advice from people who know things is always welcome.
Yes, this is totally possible. The only thing you need to make sure is, that the managers/engineers submit their form against your web service as string like shown in this screenshot.
The Reason why you need to submit the form as string is simple - you cannot configure IP to send XmlDocument object's directly. It is possible, however you need custom code in each form you/your cowokers create, so i'd suggest using the no-code solution.
Heres how you could implement the web service method.
[WebMethod]
public void CreateTable(string infoPathData)
{
var doc = new XmlDocument();
doc.LoadXml(infoPathData);
//gets the namespace uri - it is unique for each form
string nsUri = doc.ChildNodes[3].Attributes["xmlns:my"].Value;
var nsManager = new XmlNamespaceManager(doc.NameTable);
nsManager.AddNamespace("my", nsUri);
//select the myField node
var root = doc.SelectSingleNode("my:myFields", nsManager);
var sqlStatement = new StringBuilder();
sqlStatement.Append("CREATE TABLE ....");
foreach (XmlNode n in root.ChildNodes)
{
//n.Name - gets the name of the node (incl. NS)
//n.InnerText - gets the field value
//append to sqlStatement
}
//execute sql statement ...
}
You build an XmlDocument from the submitted IP data and then iterate it's fields. Depending on your requirements, you might also need to iterate child-nodes (i.e. if the form includes folders/repeating tables etc.) but thats really up to you ;-)
If you never worked with XmlDocument's before, be sure to check out this link http://msdn.microsoft.com/en-us/library/system.xml.xmldocument.aspx
You will need to enforce some specific rules to people who use your web service like what happens when someone renames "my:myFields" to "my:myBlaBla" (which is possible) and submits his/her form to your web service. Also i suggest very heavy error-logging, because things can (and will!) go wrong with such a generic approach.
The only problem which i can think of is how to determine the data-type of each field because it is not included in the InfoPath form data. You could try the usual C# Conversion methods (like Int32.TryParse etc).
Hope this helps :-)

Categories