Klingt schonmal super und scheint nicht so einfach zu sein.. Habe allerdings einige Fragen:
Die Ergebnisse wie von deerhunter sind in Ordnung, eine kommaseparierte Liste wäre auch akzeptabel..
verwendetes Datenbanksystem: MySQL
Hallo,
ich habe in meiner Datenbank zwei Tabellen: Warenkorb und Artikel. Diese haben folgenden Inhalt:
TABLE_WARENKORB
WID Kunde
001 CustomerA
002 CustomerB
003 CustomerC
004 CustomerD
005 CustomerE
006 CustomerF
007 CustomerG
008 CustomerH
009 CustomerI
TABLE_ARTICLE
ID WID Article
01 001 Buch
02 001 Föhn
03 001 Bier
04 002 Buch
05 002 Bier
06 003 Buch
07 003 Bier
08 003 Föhn
09 004 Föhn
10 004 Schal
11 005 Föhn
12 005 Buch
13 005 Bier
14 006 Buch
15 006 Bier
16 006 Föhn
17 007 Buch
18 007 Bier
19 008 Schal
20 008 Föhn
21 009 Schal
22 009 Bier
...
Nun möchte ich herausfinden, welche Warenkörbe IDENTISCH sind. Also folgende Ergebnisse:
Über INTERSECT kann ich ja zwei SELECTS "vergleichen" ... aber damit kann ich ja nur Abfragen ob beispielsweise Warenkorb 001 und 002 identisch sind. Könnte ich zumindest irgendwie abfragen, ob es Warenkörbe gibt, die identisch mit 001 sind?
Danke und Gruß
Naja keine Fehlermeldung, aber die Ergebnistabelle ist leer unter bestimmten Umständen ... z.B. wenn es immer identisch viele Personen gibt zu einem Auftrag ...
Das funktioniert leider nicht 😦
@Viper: danke für das Beispiel. Ich will die Abfrage jedoch allgemeingültig machen und nicht konkret für dieses Beispiel ..
@witte: kannst du bitte ein Beispielstatement schreiben?
Nein, Hans darf nicht im Ergebnis enthalten sein ...
Hallo,
ich möchte in meinen Datenbanken eine "spezielle" Gruppierungsabfrage machen (ähnlich wie ein KgV). Dazu habe ich bspw. folgende Datensätze:
tbl_Person
ID / Name
0 / Hans
1 / Tom
2 / Marta
3 / Norbert
tbl_Auftrag
Auftragsnr / Person
1000 / 0
1000 / 1
1000 / 3
2010 / 1
2010 / 2
2010 / 3
3015 / 1
3015 / 3
4540 / 0
4540 / 1
4540 / 2
4540 / 3
Nun möchte ich mit einem SQL Statement herausfinden, welche Personen bei allen aufgelisteten Aufträgen beteiligt waren. In diesem Falle also Person 1 und 3:
An Auftrag 1000 ist Person 1 und 3 beteiligt
An Auftrag 2010 ist Person 1 und 3 beteiligt
An Auftrag 3015 ist Person 1 und 3 beteiligt
An Auftrag 4540 ist Person 1 und 3 beteiligt
Ich möchte also Personen 1 und 3 als Datensätze erhalten. Hat jemand eine Idee?
Danke im Voraus!
Sorry. Nein bekomme keine Fehlermeldung. Das Ding stürzt direkt ab... 😦
Windows Presentation Foundation Host hat ein Problem festgestellt und muss beendet werden.
AppName: presentationhost.exe AppVer: 4.0.40305.0 ModName: kernel32.dll
ModVer: 5.1.2600.5781 Offset: 00012afb
Hallo,
ich habe Firefox 3.6 und mein WPF-Presentation Host stürzt bei jeder WPF Anwendung ab ... kennt jemand das Problem? Neu installation von Firefox hat nichts gebracht 😦
Danke und Gruß.
Ich bin kein Fachinformatiker weshalb ich zum Thema Gehälter nichts sagen kann. Aber mal eine ernste Frage: wenn du nicht zufrieden bist und gehaltstechnisch keine großen Aussichten hast, wieso machst du dich nicht selbständig?
MfG
Hallo,
ich habe ein Word-Add In erstellt, welches ich direkt aus VS heraus testen kann. In Word erscheint dann das zugehörige Ribbon und ich kann auch über die Word-Optionen das Add-In manuell entfernen. Wenn ich nun jedoch die erstellte .DLL manuell "installieren" will über Word, bekomme ich die Meldung, dass die DLL kein gültiges Add-In sei. Wieso? Wie kann ich denn nun bei meinem Kollegen das Plugin installieren?
Vielen Dank für eure Hilfe!
Hallo,
ist es möglich aus einem bestehenden XSD ein Datenmodell ZUR LAUFZEIT zu erstellen. D.h. der Benutzer soll zur Laufzeit in einem Treeview basierend auf dem XSD Daten eingeben können, die dann als XML gespeichert werden.
Beispiel:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="test"
targetNamespace="http://tempuri.org/test.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/test.xsd"
xmlns:mstns="http://tempuri.org/test.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="html">
<xs:complexType>
<xs:sequence>
<xs:element ref="head"/>
<xs:element name="body" type="xsd:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="head">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xsd:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Klickt der User mit der rechten Maustaste in das TreeView so soll er lediglich die Möglichkeit haben, ein "html"-Element zu erstellen (aber eben nur einmal). Klickt er nun rechts auf "html"-Element os kann er ein "head" oder "body" Element erstellen.. Auch hier nur jeweils einmal....
Da das XSD dynamisch zur Laufzeit geändert werden kann, muss ich das Datenmodell zur Laufzeit erstellen. Über XMLDocument.Load("bla.xsd") komme ich nicht weit....
Bin für jeden Tip dankbar...
Ich habe folgende Idee, wie ich das ganze nun (performant) lösen will:
public class CustomerViewObject
{
public int Id { get; set; }
public String Vorname { get; set; }
public String Nachname { get; set; }
public String Wohnhaft { get; set; }
public CustomerViewObject(Customer customer)
{
this.Id = customer.Id;
this.Vorname = customer.Person.FirstName;
this.Nachname = customer.Person.LastName;
this.Wohnhaft = customer.FirstAddress.ZIP + " " + customer.FirstAddress.Location + ", " + customer.FirstAddress.Street;
}
}
public class DomainContext : NHibernateContext
{
public DomainContext(ISession session)
: base(session)
{
}
public IOrderedQueryable<Customer> Customers
{
get
{
return Session.Linq<Customer>();
}
}
public IOrderedQueryable<Person> Persons
{
get
{
return Session.Linq<Person>();
}
}
public IOrderedQueryable<Address> Address
{
get
{
return Session.Linq<Address>();
}
}
}
public void FillGridWithAllCustomers()
{
Stopwatch s = new Stopwatch();
s.Start();
var session = DataBase.GetFactory().OpenSession();
using (var context = new DomainContext(session))
{
var customers = (from n in context.Customers
select new CustomerViewObject(n));
_gridControl.DataSource = customers.ToList(); <<< Exception
}
s.Stop();
}
Ich habe allerdings das Problem, dass in der dick markierten Zeile folgende Exception kommt:
QueryException: could not instantiate: Onvestor.DAL.CustomerViewObject
Das liegt sicherlich daran, dass das Customer-Objekt (welches ich ja meinem CustomerViewObject mitgebe) nur "Lazy" geladen wird... wie kann ich in meinem DomainContext das CustomerObjekt am elegantesten vollständig laden?
Wäre um jede Hilfe dankbar 😃
Das mache ich sowieso, da ich bspw. "Id" nicht anzeigen will... aber das löst nicht mein eigentliches "Problem". Mir fehlt irgendwie die generelle Vorgehensweise.
Ich habe eine Datenbankabfrage (NHibernate) und bekomme eine IList<Customer> zurück. Ich möchte jedoch zu jedem Customer auch die entsprechende Adresse, Vorname und Nachname im Datagridview anzeigen (Die CustomerId blende ich über BrowsableAttribute aus). Derzeit erhalte ich durch Bindung des IList<Customer> an das DGV nur die Spalte: "Person" und jede Row enthält eben die Person.ToString() Methode... was bspw. zu Werten wie "PersonProxya42af78769dc4c4dbe92ac4e6962f188" führt.
Muss ich...
Oder muss ich...
Das mit dem Dummy Objekt werde ich nicht machen > zu langsam.
Hallo,
ich habe 3 Entitities: Customer, Person und Address:
public class Customer
{
public int CustomerId { get; private set; }
public Person Person { get; set; }
}
public class Person
{
public int PersonId { get; private set; }
public String FirstName { get; set; }
public String LastName { get; set; }
public Address Address { get; set; }
}
public class Address
{
public int AddressId { get; private set; }
public String Street { get; set; }
}
Was meint ihr, wie sollte ich an die Sache dran gehen? Über ein "Dummy"-Objekt?
public class Dummy
{
public int CustomerId { get; set; }
public String Street { get; set; }
public String FirstName { get; set; }
public String LastName { get; set; }
}
Vielleicht habt ihr bessere Vorschläge... weil mir gefällt das nicht.
Danke im Voraus und Gruß
War einfacher als gedacht ... hier die Lösung:
...
_sessionFactory = Fluently.Configure()
.Database(SQLiteConfiguration.Standard.UsingFile(DatabaseFile))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<Program>())
.ExposeConfiguration(BuildSchema)
.BuildSessionFactory();
}
private static void BuildSchema(Configuration config)
{
if (!File.Exists(DatabaseFile))
new SchemaExport(config).Create(true, true);
new SchemaValidator(config).Validate();
}
verwendetes Datenbanksystem: SQLite
Hallo,
ich möchte gerne eine erzeugte SQLite Datenbank auf das aktuelle Datenbankschema validieren. Ändern sich meine POCO's erhalte ich beim DB-Zugriff eine ADO.NET-Exception. Dies will ich vermeiden und gerne beim Start des Programms überprüfen, ob das Schema zur DB-Datei passt... Ich verwende NHibernate und Fluent.
Wie könnte man das am besten lösen?
Danke und Gruß!
Vielen lieben Dank für eure Vorschläge!
Ich möchte in meinem Programm eine Funktion anbieten, die es dem Benutzer ermöglicht Makros aufzuzeichnen, abzuspeichern und abzuspielen.
Dazu war meine Überlegung, eine Events-Liste mit allen gestarteten Events zu führen (z.B. Button1_Clicked). Wenn das Makro abgespielt werden soll, starte ich alle in der Liste vorhandenen Events.
Könnte das ganze so klappen oder wie würdet ihr das realisieren?
@herbi: das mit der eigenen Sprache (z.B. XML) wäre natürlich das Optimum, weiß jedoch nicht wie ich sowas implementieren könnte mit überschaubarem Aufwand.
Ich werde mir den Ansatz mit dem Synchronisieren mal genauer anschauen oder eben beim "Manuellen" abfragen landen.
Vielen Dank.
Hallo,
auf meinem Formular befinden sich mehrere Controls, die untereinander abhängig sind:
Control A sei eine Checkbox.
Control B sei eine Combobox.
Control C sei ein Textfeld.
Wird das Formular geöffnet, so sind Control B und C disabled und nur Control A enabled. Wenn der User nun Control A "checked", so soll Control B "enabled" sein. Wählt der User nun einen Eintrag in der Liste von Control B aus, so wird Control C "freigeschalten". "Unchecked" der User wieder Control A, so wird Control B und C wieder "disabled".
Manuelles setzen von den entsprechenden Properties in den Events ist sehr fehleranfällig bei komplexeren Abhängigkeiten.
Hat jemand Ideen bzw. Tips?
Nein, noch nicht, verstehe aber auch nicht, was mir das bringen sollte?
Hier ein Beispiel-XML:
<workflow>
<ifelsebranch>
<ifelse condition="...">
<dosomething1 />
<dosomething2 />
</ifelse>
<ifelse condition="...">
<dosomething3 />
<ifelsebranch>
<ifelse condition="...">
<ifelsebranch>
<ifelse condition="..."> </ifelse>
</ifelsebranch>
</ifelse>
<ifelse condition="...">
<dosomething5 />
</ifelse>
</ifelsebranch>
</ifelse>
<ifelse condition="...">
<dosomething4 />
</ifelse>
</ifelsebranch>
</workflow>
Aus diesem XML möchte ich bspw. folgendes Script erzeugen:
if(...)
{
dosomething1();
dosomething2();
}
else if(...)
{
dosomething3();
if(...)
{
if(...) { ... }
}
else if(...)
{
dosomething5();
}
}
else if(...)
{
dosomething4();
}
Ich weiß nicht wie ich solche Verschachtelungen rekursiv lösen kann... vielleicht kann mir jemand helfen 😦
Ich möchte eine saubere Lösung und nicht Zeile für Zeile das XML durchgehen wie wenns ein sturer Text wäre ..
Dass ich ein .XOML wieder als Workflow einlesen kann, das weiß ich g. Mir gehts darum, dass ich aus einem Workflow eine Art "Ablaufscript" erstellen will (egal welche Sprache). Das Ablaufscript wird von einem anderen Programm verwendet (es versteht keine .XOML's).
Z.B. möchte ich aus 3 Delay Activities hintereinander folgendes erstellen:
...
sleep(1000);
sleep(500);
sleep(800);
...
Nun möchte ich aber auch IfElseAbzweigungen berücksichtigen, um z.B. sowas zu erstellen:
if (...)
{
sleep(1000);
}
else if(...)
{
...
}
else
....
Relativ unspektakulär, ja. Wenn ich nun aber ineinanderverschachtelte IfElseBranches in meinem Workflow habe, weiß ich jedoch nicht wie ich die Sache (rekursiv) angehe... vllt. gibts ja auch eine einfacherer Lösung.
Vllt hat jemand schonmal sowas gemacht?
Hallo,
ich möchte gerne aus meinem Workflow-Design ein Script zur Laufzeit generieren lassen. Dazu war mein erster Ansatz die XOML Datei zu "parsen" und entsprechend dann den Code Stück für Stück zu bauen. Allerdings ist das ganze etwas komplexer als gedacht, insbesondere wenn IfElseActivities enthalten sind! Habe leider keinen vernünftigen Ansatz wie ich das ganze machen könnte... vllt ist es ja einfacher als gedacht?!
Was schlagt ihr vor?
Ok, ich kann das Verhalten nun nachvollziehen... Danke!
Wie kann ich jedoch Form1.m_obj aus Form2 möglichst "elegant" zurücksetzen?
Die Variable m_obj von Form1 zeigt weiterhin auf das "alte" Objekt.
Das ist doch eine Referenz oder nicht? Form2.m_obj == Form1.m_obj oder habe ich was übersehen?
Huhu,
ich habe ein (für mich) unverständliches Programmverhalten. Hier erstmal der Code, danach die Erklärung...
public class ObjectSerializer
{
public string SerializedString { get; set; }
private string UTF8ByteArrayToString(byte[] characters)
{
UTF8Encoding encoding = new UTF8Encoding();
string constructedString = encoding.GetString(characters);
return (constructedString);
}
private Byte[] StringToUTF8ByteArray(String pXmlString)
{
UTF8Encoding encoding = new UTF8Encoding();
Byte[] byteArray = encoding.GetBytes(pXmlString);
return byteArray;
}
public String SerializeObject(Object pObject)
{
try
{
String XmlizedString = null;
MemoryStream memoryStream = new MemoryStream();
XmlSerializer xs = new XmlSerializer(pObject.GetType());
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
xs.Serialize(xmlTextWriter, pObject);
memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
SerializedString = XmlizedString;
return XmlizedString;
}
catch (Exception e)
{
System.Console.WriteLine(e);
return null;
}
}
public Object DeserializeObject(Object o)
{
XmlSerializer xs = new XmlSerializer(o.GetType());
MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(SerializedString));
XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);
return xs.Deserialize(memoryStream);
}
}
Nun der Programmcode, der einwandfrei funktioniert (auf Form1!):
private void button1_Click(object sender, EventArgs e)
{
ObjectSerializer sm_obj = new ObjectSerializer();
sm_obj.SerializeObject(m_obj);
Form2 frm = new Form2(m_obj);
if (frm.ShowDialog() == DialogResult.Cancel)
{
m_obj = (myObject)sm_obj.DeserializeObject(m_obj);
}
LoadData();
}
Nun möchte ich eben die Serialisierung und Deserialisierung nicht auf Form1 durchführen, sondern auf Form2. Hier der Code der NICHT funktioniert:
FORM1:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2(m_obj);
frm.ShowDialog();
LoadData();
}
FORM2:
public partial class Form2 : Form
{
ObjectSerializer sm_obj = new ObjectSerializer();
private myObject m_obj;
public Form2(myObject obj)
{
InitializeComponent();
m_obj = obj;
sm_obj.SerializeObject(m_obj);
}
// ... tue irgendwas mit dem Objekt
// ... m_obj.Hobbys.Add( ... );
// ... m_obj.Vorname = "Hansi";
// ... usw...
private void btnCancel_Click(object sender, EventArgs e)
{
m_obj = (myObject)sm_obj.DeserializeObject(m_obj);
MessageBox.Show(sm_obj.SerializedString); // Gibt in XML Form das ursprüngliche Objekt aus --> allerdings wird m_obj nur zum Teil zurückgesetzt... !
}
}
Und hier noch meine Testklasse:
public class myHobby
{
private int Id { get; set; }
public string Bezeichnung { get; set; }
public myHobby()
{
//Do nothing.
}
public myHobby(int id, string bezeichnung)
{
Id = id;
Bezeichnung = bezeichnung;
}
public override string ToString()
{
return this.Bezeichnung + " (" + this.Id + ")";
}
}
public class myBeruf
{
public int Id { get; set; }
public string Bezeichnung { get; set; }
public myBeruf()
{
//Do nothing.
}
public myBeruf(int id, string bezeichnung)
{
Id = id;
Bezeichnung = bezeichnung;
}
public override string ToString()
{
return this.Bezeichnung + " (" + this.Id + ")";
}
}
public class myObject
{
private int Id { get; set; }
public string Nachname { get; set; }
public string Vorname { get; set; }
public string PLZ { get; set; }
public string Wohnort { get; set; }
public myBeruf Beruf { get; set; }
public List<myHobby> Hobbys { get; set; }
public myObject()
{
//Do nothing.
}
public myObject(string nachname, string vorname, string plz, string wohnort, myBeruf beruf, List<myHobby> hobbys)
{
Nachname = nachname;
Vorname = vorname;
PLZ = plz;
Wohnort = wohnort;
Beruf = beruf;
Hobbys = hobbys;
}
Nun kurz nochmal zum Verhalten:
Wenn ich meine Serialisierung und Deserialisierung auf Form1 durchführe, funktioniert alles einwandfrei (auch die public List<myHobby> Hobbys !).
Wenn ich die Serialisierung und Deserialisierung auf Form2 durchführe, so funktioniert es nicht vollständig. Die Änderungen an public List<myHobby> Hobbys werden nicht zurückgesetzt. Der SerializedString ist jedoch definitiv korrekt, wenn ich ihn ausgebe! Wieso wird das Objekt nicht auf seinen ursprünglichen Stand zurückgesetzt?
OK, ich habe nun deinen Post nachvollziehen können. Ich habe es nun so implementiert, aber es funktioniert leider nicht so wie es soll - eigentlich gar nicht.
Hier der Original Code, welcher funktioniert:
public class myObject : BusinessObject
{
private int Id { get; set; }
public string Nachname { get; set; }
public string Vorname { get; set; }
public string PLZ { get; set; }
public string Wohnort { get; set; }
public myBeruf Beruf { get; set; }
public List<myHobby> Hobbys { get; set; }
public myObject()
{
//Do nothing.
}
public myObject(string nachname, string vorname, string plz, string wohnort, myBeruf beruf, List<myHobby> hobbys)
{
Nachname = nachname;
Vorname = vorname;
PLZ = plz;
Wohnort = wohnort;
Beruf = beruf;
Hobbys = hobbys;
}
}
public class myHobby : BusinessObject
{
private int Id { get; set; }
public string Bezeichnung { get; set; }
public myHobby()
{
//Do nothing.
}
public myHobby(string bezeichnung)
{
Bezeichnung = bezeichnung;
}
public override string ToString()
{
return this.Bezeichnung+" ("+this.Id+")";
}
}
public class myBeruf : BusinessObject
{
public int Id { get; set; }
public string Bezeichnung { get; set; }
public myBeruf()
{
//Do nothing.
}
public myBeruf(int id, string bezeichnung)
{
Id = id;
Bezeichnung = bezeichnung;
}
public override string ToString()
{
return this.Bezeichnung + " ("+this.Id+")";
}
}
Funktioniert soweit sehr gut, auch mit der Liste public List<myHobby> Hobbys.
Wie bereits erwähnt, möchte ich nun aber myObject, myHobby und myBeruf nicht von BusinessObject ableiten. Deshalb dein Lösungsvorschlag, den ich wie folgt implementiert habe:
public class myHobby { ... }
public class myBeruf { ... }
public class myObject
{
// ...
public TMyBeruf Beruf { get; set; }
public List<TMyHobby> Hobbys { get; set; }
//public myObject()
public myObject(string nachname, string vorname, string plz, string wohnort, TMyBeruf beruf, List<TMyHobby> hobbys)
{
//...
}
}
// Interface
public interface ITransactional
{
void StartTransaction();
void CommitTransaction();
void RollbackTransaction();
}
public class TMyObject : myObject, ITransactional
{
private BusinessObject bObj = new BusinessObject();
public void StartTransaction() { bObj.StartTransaction(); }
public void CommitTransaction() { bObj.CommitTransaction(); }
public void RollbackTransaction() { bObj.RollbackTransaction(); }
}
public class TMyBeruf : myBeruf, ITransactional
{
private BusinessObject bObj = new BusinessObject();
public void StartTransaction() { bObj.StartTransaction(); }
public void CommitTransaction() { bObj.CommitTransaction(); }
public void RollbackTransaction() { bObj.RollbackTransaction(); }
}
public class TMyHobby : myHobby, ITransactional
{
private BusinessObject bObj = new BusinessObject();
public void StartTransaction() { bObj.StartTransaction(); }
public void CommitTransaction() { bObj.CommitTransaction(); }
public void RollbackTransaction() { bObj.RollbackTransaction(); }
}
Wenn ich mit TMyHobby, TMyBeruf und TMyObject arbeite, funktioniert das ganze Rollback etc. nicht mehr... auch nicht bei einfachen Properties wie "Nachname" o.ä...
Du rufst die Funktion tbPlatineAdd_Click explizit beim FormLoad auf. Versuchs mal beim FormShown.
Die Controls befinden sich beim FormLoad eigentlich noch nicht auf dem Formular, deshalb kann auch kein Focus gesetzt werden.
Ich kann nicht ganz folgen...? Sorry...
Ich habe folgende automatisch generierte Klasse (einfache Klasse) mit einer Eigenschaft Nachname und ID:
public partial class person : global::System.Data.Objects.DataClasses.EntityObject
{
public static person Createperson(int id) { ... }
public int ID { get { ... } { set { ... } }
private int _ID;
partial void OnIDChanging(int value);
partial void OnIDChanged();
public string Nachname { get { ... } { set { ... } }
private string _Nachname;
partial void OnNachnameChanging(string value);
partial void OnNachnameChanged();
}
Nun muss ich ja person von BusinessObject ableiten, um meine Methoden StartTransaction, CommitTransaction und RollBackTransaction für ein person-Object zur Verfügung zu stellen.
Was ist mit eventuell vorhandenen Listen oder Objekten, die auch wieder BusinessObject implementiert haben müssten (bezogen auf Klasse person)?
Kannst du mir das bitte nochmals anhand eines Beispiels (in Anlehnung an der Klasse person) demonstrieren?
Womöglich macht die Verwendung von ADO.NET Entities oder LINQ TO SQL im Zusammenhang mit BusinessObject wenig Sinn. Ich habe schließlich nicht nur eine Klasse, die BusinessObject implementieren müsste...
Danke dir!
Sorry, dass ich das Thema wieder rauskrame 😉
Guter Thread. Habe diese Klasse nun mal ausprobiert... funktioniert soweit ganz wunderbar - genau das was ich schon lange gesucht habe.
Nun wollte ich diese Klasse im Zusammenhang mit ADO.NET for Entities und LINQ verwenden. Wie kann ich denn nun meine automatisch generierten Klassen (z.B. Klasse "Person") als BusinessObjects definieren? C# unterstützt ja leider keine Mehrfachvererbung... 😦
Ich habe folgendes "Problem".
Ich habe eine Liste mit Objekten, z.B. List<Berufe> m_berufe.
Diese Liste möchte ich einem Formular übergeben. Es wird eine Kopie von m_berufe erzeugt -> copy_berufe. Zu Beginn haben beide Listen denselben Inhalt - logisch. Nun kann der Benutzer Änderungen an copy_berufe durchführen, OHNE DASS ÄNDERUNGEN direkt an m_berufe gemacht werden. Schließt der Benutzer das Formular, so soll ein Abgleich zwischen m_berufe und copy_berufe durchgeführt werden. Änderungen werden dann auf Wunsch in m_berufe übernommen.
ID Bezeichnung Bemerkung
1 Tellerwäscher Toller Beruf
2 Ingenieur Scheiß Beruf
3 Berater Abwechslungsreich!!
ID Bezeichnung Bemerkung
1 Tellerwäscher Toller Beruf
2 Ingenieur Scheiß Beruf
3 Berater Abwechslungsreich!!
ID Bezeichnung Bemerkung
1 Tellerwäscher Scheiß Beruf
2 Ingenieur Guter Beruf
3 IT-Berater Man muss viel reisen
ID Bezeichnung Bemerkung
1 Tellerwäscher Scheiß Beruf
2 Ingenieur Guter Beruf
3 IT-Berater Man muss viel reisen
Obwohl ich kein "Anfänger" in C# bin, scheint mir das als gar nicht so einfach zu lösen, oder lieg ich da falsch??
Für sowas kann man auch die DB-Transaktionen benutzen. Änderungen direkt in die Tabellen schreiben. Wird zum Schluss Abbrechen gedrückt -> Rollback, ansonsten wird ein Commit ausgeführt.
Was auch eine Möglichkeit ist, das die Änderungen in eine lokale DB geschrieben werden und erst beim Commit/Schreiben in die echte DB übertragen werden.
Sowas ist mir auch schon im Kopf rumgeschwirrt ...
Hmm, wie hast du denn die Cancel Methode implementiert wenn man fragen darf?
Hallo,
ich habe eine Übersichtsliste, die z.B. Personen mit ihren Adressen anzeigt. Nun habe ich einen Button "Bearbeiten", welcher die ausgewählte Person an das Formular übergibt. Änderungen an dieser Person sollen erst in der Datenbank übernommen werden, wenn ich "Speichern" klicke. Ich mache also kein Databinding sondern habe mir eine eigene Formularklasse geschrieben, die die Properties des übergebenen Objekts erst "setzt", wenn auf Speichern geklickt wird. Funktioniert auch prima. Nun zur eigentlichen Herausforderung...
Jede Person kann Dateianhänge besitzen (z.B. Bilder, Dokumente, usw...). Diese habe ich in einer Extra Tabelle in meiner Datenbank angelegt (TBL_ANHANG mit zugehöriger Personen-ID).
Im Bearbeiten-Formular sollen diese Anhänge in einer Datagridview bearbeitet werden können (Löschen, Hinzufügen, Bearbeiten). Wird der Löschen Button geklickt wird der Eintrag aus der Anhang-Liste entfernt, soll aber noch nicht direkt aus der Datenbank gelöscht werden, erst wenn der Benutzer auf "Speichern" klickt. Dasselbe gilt für Hinzufügen und Bearbeiten.
Wie könnte man dies am besten realisieren? Oder gehe ich das ganze falsch an?
Ohje, hat sich erledigt...
AutoSize muss auf "true" gesetzt werden - wird ein Label während der Laufzeit erzeugt befindet sich der Wert dieser Property auf "false".
Vielleicht hilfts jemand 😃
Kann man irgendwie den Umbruch des Textes in einem Label vermeiden?? Ich find nichts ...
Okay danke, werd ich mal versuchen. Dachte es gibt bereits eine implementierte Möglichkeit.
Hallo,
ich habe eine DataGridView.DataSource an eine BindingList gebunden.
Nun möchte ich einen bestimmten Eintrag (bzw. Zeile) in meinem BindingList (bzw. DataGridView) suchen und automatisch markieren.
Bei einer BindingSource steht mit die Funktion BindingSource.Find(...) zur Verfügung, die jedoch bei einer BindingList nicht vorhanden ist.
Hat jemand einen Tipp?
Ja das war auch meine ursprüngliche Idee, aber mir war's zu aufwendig ne Kopie zu erstellen. Habe jetzt aber über das Begin, End und CancelEdit eine solche Möglichkeit eingebaut und werde dies wohl auch so machen ...
Ich finds nur schade, dass es grundsätzlich nativ die Möglichkeit gibt, aber nicht so funktioniert, wie sie sollte (ich bin ja nicht der einzige mit dem Problem).
Meiner übernimmt IMMER die Änderungen .. erst wenn ich eigene BeginEdit CancelEdit usw schreibe, habe ich auch die MÖglichkeit zum "Cancel"...
Wird jedoch eine MessageBox geöffnet, wird trotzdem EndEdit aufgerufen, obwohl ich es NICHT will .... (z.B. "Wollen Sie die Änderungen wirklich speichern?" -> User klickt auf Nein -> Änderungen werden trotzdem übernommen... kotz)
m_bindingsource.Current ist bei mir schon korrekt, anders funktionierts nich.. (oder liegt irgendwo in der Datenbinding der fehler?)
Das Problem scheint definitiv ein anderes zu sein, aber ich finds einfach nicht... Ich poste mal alle relevanten Stellen... !
Wird eine MessageBox aufgerufen, so wird automatisch ein EndEdit aufgerufen, nach dem auf "JA" oder "NEIN" geklickt wurde. Kann man die "Automation" vollständig abschalten? Ich würde gerne BeginEdit(); CancelEdit(); und EndEdit() ausschließlich manuell aufrufen ...
IEditableObject eingebunden:
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using System.Reflection;
using System.Windows.Forms;
namespace BusinessObjects
{
public abstract class ObjectBase : System.ComponentModel.IEditableObject
{
Hashtable props = null;
#region IEditableObject Members
public void BeginEdit()
{
if (null != props) return;
PropertyInfo[] properties = (this.GetType()).GetProperties(BindingFlags.Public | BindingFlags.Instance);
props = new Hashtable(properties.Length - 1);
for (int i = 0; i < properties.Length; i++)
{
if (null != properties[i].GetSetMethod())
{
object value = properties[i].GetValue(this, null);
props.Add(properties[i].Name, value);
}
}
}
public void CancelEdit()
{
if (null == props) return;
PropertyInfo[] properties = (this.GetType()).GetProperties(BindingFlags.Public | BindingFlags.Instance);
for (int i = 0; i < properties.Length; i++)
{
if (null != properties[i].GetSetMethod())
{
object value = props[properties[i].Name];
properties[i].SetValue(this, value, null);
}
}
props = null;
}
public void EndEdit()
{
props = null;
}
}
}
Klasse von ObjectBase ableiten:
public class ListViewObject_wndPersonen : ObjectBase { ... }
Bearbeiten-Button-Routine:
private void btnBearbeiten_Click(object sender, EventArgs e)
{
cm.Refresh();
frmPerson frm = new frmPerson(m_bindingsource);
frm.ShowDialog();
//Datenanzeige im datagridview aktualisieren
dataGridView1.Invalidate();
}
frmPerson:
public frmPerson(BindingSource bs)
{
InitializeComponent();
//Verweis auf Person einholen
m_bindingsource = bs;
m_originalobject = ((ListViewObject_wndPersonen)m_bindingsource.Current).Person;
//Databinding auf Steuerelemente
textBoxVorname.DataBindings.Add(new Binding("Text", m_bindingsource.Current, "Person.Vorname"));
//...
}
private void btnAbbrechen_Click(object sender, EventArgs e)
{
//Abbrechen Button ist immer erlaubt ...
m_bindingsource.CancelEdit();
//keine Validierung durchführen ...
this.CanClose = true;
}
private void frmPerson_FormClosing(object sender, FormClosingEventArgs e)
{
//Darf das Form geschlossen werden?
if (!this.CanClose)
{
e.Cancel = true;
}
m_bindingsource.EndEdit(); // < wird beim Schließen des Formulars NICHT automatisch aufgerufen
}
Ich hoffe, dass ich nun alles vom "logischen" her korrekt gemacht habe und einigen mit ähnlichen Problemen helfen konnte...
cm.Refresh() is überflüssig, gehört da nicht rein - sind noch Reste aus der vorherigen Implementierung...
Ich wechsle im frmPerson allerdings keinen Datensatz...
EDIT:
Mein Gott... warum funktioniert das nicht . Muss ich irgendn Interface in meiner Klasse "Person" implementieren?
Hi!
Probierma, der
frmPerson
diedataGridView1.DataSource as BindingSource
mitzugeben. Da ist ja die gewünschte Person als.Current
enthalten.
Und zur Übernahme der ÄnderungenBindingSource.EndEdit()
ausführen.
Nix mitcontext.SaveChanges()
Ich habe noch eine Frage bzgl. bindingsource.CancelEdit(): Warum funktioniert es im folgenden Code nicht, dass meine Änderungen am DataSource "rückgängig" gemacht werden?
Hier der Code meines frmMain:
//1. Abfrage..
//2. Databinding
m_bindingsource= new BindingSource();
m_bindingsource.DataSource = allData; //LINQ Resultat ...
dataGridView1.AutoGenerateColumns = false;
dataGridView1.DataSource = m_bindingsource;
//...irgendwann dann mal ein Formular aufrufen, welches den aktuellen Datensatz bearbeiten kann
frmPerson frm = new frmPerson(dataGridView1.DataSource as BindingSource);
if (frm.ShowDialog() == DialogResult.OK)
{
//Änderungen an Datasource übernehmen
m_bindingsource.EndEdit();
//Änderungen in Datenbank übernehmen
//m_context.SaveChanges();
//DGV aktualisieren
cm.Refresh();
dataGridView1.Invalidate();
}
else
{
//Durchgeführte Änderungen an Datasource verwerfen
m_bindingsource.CancelEdit();
//FUNKTIONIERT LEIDER NICHT ...
}
Hier der Code von frmPerson
public frmPerson(BindingSource bs)
{
InitializeComponent();
//Verweis auf Person einholen
m_bindingsource = bs;
m_originalobject = ((ListViewObject_wndPersonen)m_bindingsource.Current).Person;
//Databinding an Steuerelemente um Änderungen am Objekt durchzuführen
textboxVorname.DataBindings.Add(new Binding("Text", ((ListViewObject_wndPersonen)m_bindingsource.Current).Person, datamember));
//...
}
Hmmmmpf ... 😕 MSDN und Google hat mir auf Anhieb nich wirklich weitergeholfen ..
Also mein Problem ist folgendes:
Ich habe ein DataGridView welches als DataSource eine BindingList hat. Derzeit kann das DataGrid direkt im Grid geordnet werden, ohne eine neue LINQ Abfrage zu starten.
Wie sollte die Sortierung am sinnvollsten gemacht werden? HeaderColumnClick - Event abfragen und jedesmal eine neue LINQ Abfrage ausführen? Wo speicher bzw. rufe ich die aktuelle Sortierung ab?
Die Datensätze sollen via Paging erreichbar sein.
Die Datensätze sollen durchsucht werden können (und natürlich auch sortiert werden können). Die Sortierung muss ich irgendwo zwischenspeichern. Meine Idee war u.a., dass ich einfach den Ausdruck der OrderBy-Klausel speichere. Das ist ja vom Typ Expression sein. Allerdings finde ich im Netz kein Beispiel...
Vielleicht seh ich das ganze auch zu kompliziert oder ich machs vom Ansatz her "falsch". Mir ist natürlich klar, dass eine LINQ Abfrage eine Ergebnismenge ist...
Hi!
Probierma, der
frmPerson
diedataGridView1.DataSource as BindingSource
mitzugeben. Da ist ja die gewünschte Person als.Current
enthalten.
Und zur Übernahme der ÄnderungenBindingSource.EndEdit()
ausführen.
Nix mitcontext.SaveChanges()
Ok, werde ich mal versuchen. Habe aber noch zwei Fragen:
Inzwischen habe ich das Update hinbekommen mit dem CurrencyManager: an die datagridview1.datasource gebunden und dann via cm.Refresh() updaten (warum auch immer das anfangs nicht geklappt hat..)
Hallo,
ich möchte die Sortierung in einem DataGridView beibehalten, wenn ich eine Möglichkeit zum Paging integriere. Dazu muss ich irgendwie die OrderBy-Klausel zwischenspeichern.
Leider steh ich diesbzgl. derzeit auf dem Schlauch ... 😦
Verwendete Technologien: LINQ
So, ich hab nun das gesamte Forum durchgelesen bzgl CurrencyManager und ich komm einfach auf keine Lösung in meinem Fall.
Ich habe eine LINQ to ENTITIES Query - Result.. Dieses wird in einem Sortierbaren DGV angezeigt.
private void wndPersonen_Load(object sender, EventArgs e)
{
context = new oEntities();
var query = from p in context.person
orderby p.Nachname
select new ListViewObject_wndPersonen
{
Person = p,
Nachname = p.Nachname,
Vorname = p.Vorname,
Wohnort = p.PLZ + " " + p.Wohnort
};
dataGridView1.DefaultCellStyle = Vars.CellStyle;
bs = new SortableBindingList<ListViewObject_wndPersonen>(query);
dataGridView1.DataSource = bs;
dataGridView1.Columns["Person"].Visible = false;
}
Nun möchte ich via Doppelklick einen Eintrag aus meiner DGV bearbeiten können. Funktioniert auch soweit, aber mein DGV wird erst aktualisiert, wen ich die Anwendung neu starte...
private void btnBearbeiten_Click(object sender, EventArgs e)
{
frmPerson frm = new frmPerson((dataGridView1.Rows[dataGridView1.CurrentCell.RowIndex].DataBoundItem as ListViewObject_wndPersonen).Person);
if (frm.ShowDialog() == DialogResult.OK)
{
context.SaveChanges();
// HIER UPDATE ...
}
else
{
// Abbrechen geklickt...
}
}
Woran liegts? Ich hab einiges mit dem Currency Manager versucht aber hab kein Update hinbekommen... 😦
Danke für die vielen Antworten!
Wie könnte man denn ein solches Public Key-Verfahren am besten realisieren?