Why the methods of DomainService which have parameters of complex types (all types except int, bool, float,...) are not recognizable in Model?
in build and even in intelisense! :(
Update
CODE
namespace KhorasanMIS.Web.Services
{
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
using System.ServiceModel.DomainServices.EntityFramework;
using System.ServiceModel.DomainServices.Hosting;
using System.ServiceModel.DomainServices.Server;
using KhorasanMIS.Web.Entities;
// Implements application logic using the KhorasanMISEntities context.
// TODO: Add your application logic to these methods or in additional methods.
// TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
// Also consider adding roles to restrict access as appropriate.
// [RequiresAuthentication]
[EnableClientAccess()]
public class DSCountry : LinqToEntitiesDomainService<KhorasanMISEntities>
{
// TODO:
// Consider constraining the results of your query method. If you need additional input you can
// add parameters to this method or create additional query methods with different names.
// To support paging you will need to add ordering to the 'Countries' query.
public IQueryable<Country> GetCountries()
{
return this.ObjectContext.Countries;
}
public IEnumerable<Country> GetCountryByCode(string pCode)
{
return this.ObjectContext.Countries.Where(a => a.ISOCode.Equals(pCode));
}
public bool IsValidEdit(string pCode)
{
List<string> message = new List<string>();
IEnumerable<Country> list = GetCountryByCode(pCode);
if (list.Count() > 0)
{
return false;
}
return true;
}
//***********************************************************
public bool Update(Country currentItem)
{
this.ObjectContext.Countries.AttachAsModified(currentItem, this.ChangeSet.GetOriginal(currentItem));
return true;
}
//***********************************************************
}
}
The method in the stars-comment can not be used in a model but if I change its parameter to int, it will become usable.
Check out the documentation of DomainServices. Insert, update and delete operation are handled by the EntitySet and the SubmitChanges method on the client side.
When you expose a domain service, an EntitySet object is generated in the domain context with properties that indicate which operations (insert, update, or delete) are permitted from the client. You execute data modifications by modifying the entity collection and then calling the SubmitChanges method.
Related
I am trying to create a white list part for the site's settings that will allow an admin user to enter a list of urls that are considered "white listed". I'm having a problem with storing this information in the database though. When creating a new content type with information that belongs in the database you can use the following:
public class ShareBarSettingsPart : ContentPart<ShareBarSettingsPartRecord> {
public string AddThisAccount {
get { return Record.AddThisAccount; }
set { Record.AddThisAccount = value; }
}
}
to set the value of AddThisAccount in the database. My problem is I need a list of urls in the database and not just a single item. I tried the following but it gives me an error:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel.DataAnnotations;
using Orchard.ContentManagement;
using Orchard.ContentManagement.Records;
namespace Speedbump.Models
{
public class SpeedBumpSettingsRecord : ContentPartRecord
{
public virtual List<string> whiteList { get; set; }
}
public class SpeedBumpSettingsPart : ContentPart<SpeedBumpSettingsRecord>
{
public List<string> whiteList
{
get { return Record.whiteList; }
set { Record.whiteList.Add(value); } //I need to be able to add a single record to the list here
}
}
}
Any help would be greatly appreciated, thank you.
List<string> is not supported as a record property type. It doesn't matter however as you should never use a record for a site setting part. Use Store and Retrieve instead. Any existing settings part will give you an example.
I am into this wpf from last 2 weeks. I am currently developing a wpf application based on MVVM pattern. I have 2 projects inside my Solution in Visual C# 2010. One is a WPF application(lets say MSPBoardControl) and other is a Class Library(lets say ConnectViewComponent). Thus both the MSPBoardControl and ConnectViewComponent have the view, viewmodel, model classes respectively.
I have added the reference of ConnectViewComponent in my MSPBoardControl and I am able to access the member variables of ConnectViewComponent in my MSPBoardControl's View,Viewmodel and model class. My concern is how to access the member variables of MSPBoardControl from my ConnectViewComponent.
ViewModel of MSPBoardControl:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using ConnectViewComponent.Model;
using System.Windows.Input;
using ConnectViewComponent.Commands;
[[[using MSPBoardControl.ViewModel;]]]
namespace ConnectViewComponent.ViewModel
{
public class ConnectViewModel : INotifyPropertyChanged
{
public List<ConnectModel> m_BoardNames;
[[[BoardControlViewModel mBoardVM;]]]
public ConnectViewModel()
{
m_BoardNames = new List<ConnectModel>()
{
new ConnectModel() {Name = "Bavaria", Connection_Status = "Disconnected"},
new ConnectModel() {Name = "Redhook", Connection_Status = "Disconnected"},
};
}
public List<ConnectModel> BoardNames
{
//get set
}
private ConnectModel m_SelectedBoardItem;
public ConnectModel SelectedBoard
{
//get set
}
private ICommand mUpdater;
public ICommand ConnectCommand
{
get
{
if (mUpdater == null)
mUpdater = new DelegateCommand(new Action(SaveExecuted), new Func<bool>(SaveCanExecute));
return mUpdater;
}
set
{
mUpdater = value;
}
}
public bool SaveCanExecute()
{
return true;
}
public void SaveExecuted()
{
if (SelectedBoard.Connection_Status == "Disconnected" && SelectedBoard.Name == "Bavaria")
{
SelectedBoard.Connection_Status = "Connected";
}
else if (SelectedBoard.Connection_Status == "Disconnected" && SelectedBoard.Name == "Redhook")
{
SelectedBoard.Connection_Status = "Connected";
}
}
}
}
[[[ -- ]]] in my code denotes I am not able to access the members of BoardControlViewModel as well as USING Namespace.ViewModel too.
I cannot add the reference of BoardControl in my ConnectComponent project since it will lead to circular dependency. How can I access it? Please Help!!
Having circular dependencies in your project can be a "code smell". There are various ways to remove this "smell". For simplicity lets say that you have project A and project B that has a circular dependency.
Factor out the common types used by both projects and move them into a new project C. Let A and B reference C. This should remove either the dependency from A to B or the opposite dependency or even both dependencies.
If A and B has types that need to interact you need to decouple this interaction into a common set of abstractions (e.g. interfaces or abstract base classes). You should then move these types without any implementation into project C that both A and B references. This will allow the types in A and B to interact but only using the definitions in C. An example could be that A is the main application. It calls in interface IService defined in C but implemented in B and registers a callback IServiceCallback defined in C via IService. B can then call back into A using IServiceCallback without knowing that the implementation is in A.
If the types in A and B are strongly coupled you should merge A and B into a single project.
You can add a some type of "Common" library (project) that will contain those general classes. So both BoardControl and ConnectComponent can reference it.
Also you can check similar question.
I am using Entity Framework 4 in my project. One basic requirement is to fetch data from database using stored procedure and loop those data in presentation layer and also bind with dropdownlist, grid control etc.
I am following the flow as follow:
PL call BLL and BLL call DAL
Sample codes :
DAL:
namespace DAL.Repository
{
public class CountryRepository
{
public static IList GetCountry(string CountryId)
{
using(MyDBEntities context=new MyDBEntities())
{
// it calls SP in DB thru EF to fetch data
return context.GetCountry(CountryId).ToList();
}
}
}
}
BLL
namespace BLL
{
public class Country
{
public static IList GetCountry(string CountryId)
{
return DAL.Repository.CountryRepository.GetCountry(CountryId);
}
}
}
PL
ddlCountry.DataTextField = "CountryName";
ddlCountry.DataValueField = "CountryId";
ddlCountry.DataSource= BLL.Country.GetCountry(string.Empty);
ddlCountry.DataBind();
* Here binding working fine. But i am not sure is it the best option. Please suggest me.
System.Collections.IEnumerator lst= BLL.Country.GetCountry(string.Empty).GetEnumerator();
while(lst.MoveNext())
{
string s = ((DAL.Entity.ORM.Country)(lst.Current)).Countryname;
/* This is the main issue. To get data from [current]
reference of [DAL.Entity.ORM.Country] is required.
It is strongly not good practice to keep reference
of DAL in PL. */
}
What is best way of fetching data from database using EF with Stored procedure and using those data Independently in PL?
Is is safe to use static method as i have used?
Please suggest me.
Ideally you don't want to reference your DAL in your PL. You could have a shared type with your PL and BL. The BL would convert your DAL type to this type before returning it.
For the example you have show yes static method should be fine.
Trying to implement a domain service in a SL app and getting the following error:
Parameter 'spFolderCreate' of domain method 'CreateSharePointFolder' must be an entity type exposed by the DomainService.
[EnableClientAccess()]
public class FileUploadService : DomainService
{
public void CreateSharePointFolder(SharePointFolderCreate spFolderCreate)
{
SharePointFolder spf = new SharePointFolder();
spf.CreateFolder_ClientOM(spFolderCreate.listName, spFolderCreate.fileName);
}
[OperationContract]
void CreateSharePointFolder(SharePointFolderCreate spFolderCreate);
[DataContract]
public class SharePointFolderCreate
{
private string m_listName;
private string m_fileName;
[DataMember]
public string listName
{
get { return m_listName; }
set { m_listName = value; }
}
[DataMember]
public string fileName
{
get { return m_fileName; }
set { m_fileName = value; }
}
}
So am I missing something simple here to make this all work?
It may be that the framework is inferring the intended operation because you have the word "Create" prefixing the function name (CreateSharePointFolder). Details of this behaviour can be found here
Although that is all fine for DomainServices and EntityFramework, following the information in that article, it can be inferred that methods beginning "Delete" will be performing a delete of an entity, so must accept an entity as a parameter. The same is true for "Create" or "Insert" prefixed methods. Only "Get" or "Select" methods can take non-entity parameters, making it possible to pass a numeric id (for example) to a "Get" method.
Try changing your method name temporarily to "BlahSharePointFolder" to see if it is this convention of inferrance that's causing your problem.
Also, as there is no metadata defined for your SharePointFolderCreate DC, you might need to decorate the class (in addition to the [DataContract] attribute) with the [MetadataType] attribute. You will see how to implement this if you used the DomainServiceClass wizard and point to an EF model. There is a checkbox at the bottom for generating metadata. Somewhere in your solution.Web project you should find a domainservice.metadata.cs file. In this file, you will find examples of how to use the [MetadataType] attribute.
For the RIA WCF service to work correctly with your own methods, you need to ensure that all entities existing on the parameter list have at least one member with a [Key] attribute defined in their metadata class, and that the entity is returned somewhere on your DomainService in a "Get" method.
HTH
Lee
I'm using nHibernate to update 2 columns in a table that has 3 encrypted triggers on it. The triggers are not owned by me and I can not make changes to them, so unfortunately I can't SET NOCOUNT ON inside of them.
Is there another way to get around the TooManyRowsAffectedException that is thrown on commit?
Update 1
So far only way I've gotten around the issue is to step around the .Save routine with
var query = session.CreateSQLQuery("update Orders set Notes = :Notes, Status = :Status where OrderId = :Order");
query.SetString("Notes", orderHeader.Notes);
query.SetString("Status", orderHeader.OrderStatus);
query.SetInt32("Order", orderHeader.OrderHeaderId);
query.ExecuteUpdate();
It feels dirty and is not easily to extend, but it doesn't crater.
We had the same problem with a 3rd party Sybase database. Fortunately, after some digging into the NHibernate code and brief discussion with the developers, it seems that there is a straightforward solution that doesn't require changes to NHibernate. The solution is given by Fabio Maulo in this thread in the NHibernate developer group.
To implement this for Sybase we created our own implementation of IBatcherFactory, inherited from NonBatchingBatcher and overrode the AddToBatch() method to remove the call to VerifyOutcomeNonBatched() on the provided IExpectation object:
public class NonVerifyingBatcherFactory : IBatcherFactory
{
public virtual IBatcher CreateBatcher(ConnectionManager connectionManager, IInterceptor interceptor)
{
return new NonBatchingBatcherWithoutVerification(connectionManager, interceptor);
}
}
public class NonBatchingBatcherWithoutVerification : NonBatchingBatcher
{
public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor) : base(connectionManager, interceptor)
{}
public override void AddToBatch(IExpectation expectation)
{
IDbCommand cmd = CurrentCommand;
ExecuteNonQuery(cmd);
// Removed the following line
//expectation.VerifyOutcomeNonBatched(rowCount, cmd);
}
}
To do the same for SQL Server you would need to inherit from SqlClientBatchingBatcher, override DoExectuteBatch() and remove the call to VerifyOutcomeBatched() from the Expectations object:
public class NonBatchingBatcherWithoutVerification : SqlClientBatchingBatcher
{
public NonBatchingBatcherWithoutVerification(ConnectionManager connectionManager, IInterceptor interceptor) : base(connectionManager, interceptor)
{}
protected override void DoExecuteBatch(IDbCommand ps)
{
log.DebugFormat("Executing batch");
CheckReaders();
Prepare(currentBatch.BatchCommand);
if (Factory.Settings.SqlStatementLogger.IsDebugEnabled)
{
Factory.Settings.SqlStatementLogger.LogBatchCommand(currentBatchCommandsLog.ToString());
currentBatchCommandsLog = new StringBuilder().AppendLine("Batch commands:");
}
int rowsAffected = currentBatch.ExecuteNonQuery();
// Removed the following line
//Expectations.VerifyOutcomeBatched(totalExpectedRowsAffected, rowsAffected);
currentBatch.Dispose();
totalExpectedRowsAffected = 0;
currentBatch = new SqlClientSqlCommandSet();
}
}
Now you need to inject your new classes into NHibernate. There are at two ways to do this that I am aware of:
Provide the name of your IBatcherFactory implementation in the adonet.factory_class configuration property
Create a custom driver that implements the IEmbeddedBatcherFactoryProvider interface
Given that we already had a custom driver in our project to work around Sybase 12 ANSI string problems it was a straightforward change to implement the interface as follows:
public class DriverWithCustomBatcherFactory : SybaseAdoNet12ClientDriver, IEmbeddedBatcherFactoryProvider
{
public Type BatcherFactoryClass
{
get { return typeof(NonVerifyingBatcherFactory); }
}
//...other driver code for our project...
}
The driver can be configured by providing the driver name using the connection.driver_class configuration property. We wanted to use Fluent NHibernate and it can be done using Fluent as follows:
public class SybaseConfiguration : PersistenceConfiguration<SybaseConfiguration, SybaseConnectionStringBuilder>
{
SybaseConfiguration()
{
Driver<DriverWithCustomBatcherFactory>();
AdoNetBatchSize(1); // This is required to use our new batcher
}
/// <summary>
/// The dialect to use
/// </summary>
public static SybaseConfiguration SybaseDialect
{
get
{
return new SybaseConfiguration()
.Dialect<SybaseAdoNet12Dialect>();
}
}
}
and when creating the session factory we use this new class as follows:
var sf = Fluently.Configure()
.Database(SybaseConfiguration.SybaseDialect.ConnectionString(_connectionString))
.Mappings(m => m.FluentMappings.AddFromAssemblyOf<MyEntity>())
.BuildSessionFactory();
Finally you need to set the adonet.batch_size property to 1 to ensure that your new batcher class is used. In Fluent NHibernate this is done using the AdoNetBatchSize() method in a class that inherits from PersistenceConfiguration (see the SybaseConfiguration class constructor above for an example of this).
er... you might be able to decrypt them...
Edit: if you can't change code, decrypt, or disable then you have no code options on the SQL Server side.
However, You could try "disallow results from triggers Option" which is OK for SQL 2005 and SQL 2008 but will be removed in later versions. I don't know if it suppresses rowcount messages though.
Setting the "Disallow Results from Triggers" option to 1 worked for us (the default is 0).
Note that this option will not be available in a future releases of Microsoft SQL Server, but after it is no longer available it will behave as if it was set to 1. So setting this to 1 now fixes the problem and also give you the same behavior as will be in future releases.