2012-03-28 6 views
0

クライアントプロジェクトと、クライアントにWCFサービスを公開するMVC3 EFモデルの最初のプロジェクトがあります。私はEFの新人ですし、いくつかのことはあまり明確ではありません。最初にEFモデル/データを使用してWCFサービスにクエリを作成する方法

特定の価格の製品を返すような単純なクエリを作成する場合は、Productエンティティを持つNorthwindサービスを想定します。クエリのコードはどこに書きますか?

サーバー側には、EDMとサービス自体しかありません。かなりストレートに、ほとんどコードがありません。私はProductモデルクラスとNorthwindContextともProdcutsPageViewModelクラスを持つクライアントで

(それがMVVMプロジェクトです)

だから私の質問は、どのように、どこで、私はDBへのクエリを作るんでしょうか? LINQコードをURIに付けることでクライアント側から作成するのですか?私はサービスに新しいメソッドを追加することによってサーバー側からそれを作るのですか?あなたがそれを初心者に説明できれば幸いです。

ありがとう!サーバーで

NorthwindODataServiceサービスクラス:クライアントProductモデルクラス上の

[ServiceBehavior(IncludeExceptionDetailInFaults = true)] 
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
public class NorthwindODataService : DataService<NorthwindEntities> 
{ 
    private readonly IUserPrivilegesRepository userPrivilegesRepository; 
    private readonly IClaimsIdentity identity; 

    public NorthwindODataService() 
     : this(HttpContext.Current.User.Identity as IClaimsIdentity, new InfrastructureEntities()) 
    { 
    } 

    public NorthwindODataService(IClaimsIdentity identity, IUserPrivilegesRepository userPrivilegesRepository) 
    { 
     this.identity = identity; 
     this.userPrivilegesRepository = userPrivilegesRepository; 
    } 

    protected string UserId 
    { 
     get 
     { 
      var nameIdentifierClaim = this.identity.Claims.SingleOrDefault(c => c.ClaimType == ClaimTypes.NameIdentifier); 
      if (nameIdentifierClaim == null) 
      { 
       throw new DataServiceException(401, "Unauthorized", "The request requires authentication.", "en-US", null); 
      } 

      return nameIdentifierClaim.Value; 
     } 
    } 

    /// <summary> 
    /// Initializes service-wide policies. This method is called only once. 
    /// </summary> 
    /// <param name="config"></param> 
    public static void InitializeService(DataServiceConfiguration config) 
    { 
     config.SetEntitySetAccessRule("Products", EntitySetRights.All); 
     config.SetEntitySetAccessRule("Categories", EntitySetRights.AllRead); 
     config.SetEntitySetAccessRule("Suppliers", EntitySetRights.AllRead); 

     config.SetEntitySetPageSize("Products", 20); 
     config.SetEntitySetPageSize("Categories", 20); 
     config.SetEntitySetPageSize("Suppliers", 20); 

     config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2; 
     config.UseVerboseErrors = true; 
    } 

    /// <summary> 
    /// Define a query interceptor for the Products entity set. 
    /// </summary> 
    /// <returns></returns> 
    [QueryInterceptor("Products")] 
    public Expression<Func<Product, bool>> OnQueryProducts() 
    { 
     this.ValidateAuthorization("Products", PrivilegeConstants.SqlReadPrivilege); 

     // The user has Read permission. 
     return p => true; 
    } 

    /// <summary> 
    /// Define a query interceptor for the Categories entity set. 
    /// </summary> 
    /// <returns></returns> 
    [QueryInterceptor("Categories")] 
    public Expression<Func<Category, bool>> OnQueryCategories() 
    { 
     this.ValidateAuthorization("Categories", PrivilegeConstants.SqlReadPrivilege); 

     // The user has Read permission. 
     return p => true; 
    } 

    /// <summary> 
    /// Define a query interceptor for the Suppliers entity set. 
    /// </summary> 
    /// <returns></returns> 
    [QueryInterceptor("Suppliers")] 
    public Expression<Func<Supplier, bool>> OnQuerySuppliers() 
    { 
     this.ValidateAuthorization("Suppliers", PrivilegeConstants.SqlReadPrivilege); 

     // The user has Read permission. 
     return p => true; 
    } 

    /// <summary> 
    /// Define a change interceptor for the Products entity set. 
    /// </summary> 
    /// <param name="product"></param> 
    /// <param name="operations"></param> 
    [ChangeInterceptor("Products")] 
    public void OnChangeProducts(Product product, UpdateOperations operations) 
    { 
     if (operations == UpdateOperations.Change) 
     { 
      this.ValidateAuthorization("Products", PrivilegeConstants.SqlUpdatePrivilege); 

      var entry = default(ObjectStateEntry); 
      if (this.CurrentDataSource.ObjectStateManager.TryGetObjectStateEntry(product, out entry)) 
      { 
       // Reject changes to a discontinued Product. 
       // Because the update is already made to the entity by the time the 
       // change interceptor in invoked, check the original value of the Discontinued 
       // property in the state entry and reject the change if 'true'. 
       if ((bool)entry.OriginalValues["Discontinued"]) 
       { 
        throw new DataServiceException(400, "Bad Request", "A discontinued product cannot be modified.", "en-US", null); 
       } 
      } 
      else 
      { 
       throw new DataServiceException(404, "Not Found", "The requested product could not be found in the data source.", "en-US", null); 
      } 
     } 
     else if (operations == UpdateOperations.Add) 
     { 
      this.ValidateAuthorization("Products", PrivilegeConstants.SqlCreatePrivilege); 
     } 
     else if (operations == UpdateOperations.Delete) 
     { 
      this.ValidateAuthorization("Products", PrivilegeConstants.SqlDeletePrivilege); 

      var entry = default(ObjectStateEntry); 
      if (this.CurrentDataSource.ObjectStateManager.TryGetObjectStateEntry(product, out entry)) 
      { 
       // Only a discontinued Product can be deleted. 
       if (!(bool)entry.OriginalValues["Discontinued"]) 
       { 
        throw new DataServiceException(400, "Bad Request", "Products that are not discontinued cannot be deleted.", "en-US", null); 
       } 
      } 
      else 
      { 
       throw new DataServiceException(404, "Not Found", "The requested product could not be found in the data source.", "en-US", null); 
      } 
     } 
    } 

    private static string BuildMessage(string entitySetName, string privilege) 
    { 
     var message = string.Empty; 
     switch (privilege) 
     { 
      case PrivilegeConstants.SqlCreatePrivilege: 
       message = string.Format(CultureInfo.InvariantCulture, "You are not authorized to create new rows in the {0} entity set.", entitySetName); 
       break; 
      case PrivilegeConstants.SqlReadPrivilege: 
       message = string.Format(CultureInfo.InvariantCulture, "You are not authorized to query the {0} entity set.", entitySetName); 
       break; 
      case PrivilegeConstants.SqlUpdatePrivilege: 
       message = string.Format(CultureInfo.InvariantCulture, "You are not authorized to update rows in the {0} entity set.", entitySetName); 
       break; 
      case PrivilegeConstants.SqlDeletePrivilege: 
       message = string.Format(CultureInfo.InvariantCulture, "You are not authorized to delete rows in the {0} entity set.", entitySetName); 
       break; 

      default: 
       message = string.Format(CultureInfo.InvariantCulture, "You are not authorized to access the {0} entity set.", entitySetName); 
       break; 
     } 

     return message; 
    } 

    private void ValidateAuthorization(string entitySetName, string privilege) 
    { 
     if (!this.userPrivilegesRepository.HasUserPrivilege(this.UserId, privilege)) 
     { 
      // The user does not have Read permission. 
      throw new DataServiceException(401, "Unauthorized", BuildMessage(entitySetName, privilege), "en-US", null); 
     } 
    } 
} 

}

ここ

は、コードの一部であります:

[EntitySetAttribute("Products")] 
[DataServiceKeyAttribute("ProductID")] 
public class Product : INotifyPropertyChanged 
{ 
    private int id; 
    private string productName; 
    private int? supplierID; 
    private int? categoryID; 
    private string quantityPerUnit; 
    private decimal? unitPrice; 
    private short? unitsInStock; 
    private short? unitsOnOrder; 
    private short? reorderLevel; 
    private bool discontinued; 

    public event PropertyChangedEventHandler PropertyChanged; 

    public int ProductID 
    { 
     get 
     { 
      return this.id; 
     } 

     set 
     { 
      this.id = value; 
      this.OnPropertyChanged("ProductID"); 
     } 
    } 

    public string ProductName 
    { 
     get 
     { 
      return this.productName; 
     } 

     set 
     { 
      this.productName = value; 
      this.OnPropertyChanged("ProductName"); 
     } 
    } 

    public int? SupplierID 
    { 
     get 
     { 
      return this.supplierID; 
     } 

     set 
     { 
      this.supplierID = value; 
      this.OnPropertyChanged("SupplierID"); 
     } 
    } 

    public int? CategoryID 
    { 
     get 
     { 
      return this.categoryID; 
     } 

     set 
     { 
      this.categoryID = value; 
      this.OnPropertyChanged("CategoryID"); 
     } 
    } 

    public string QuantityPerUnit 
    { 
     get 
     { 
      return this.quantityPerUnit; 
     } 

     set 
     { 
      this.quantityPerUnit = value; 
      this.OnPropertyChanged("QuantityPerUnit"); 
     } 
    } 

    public decimal? UnitPrice 
    { 
     get 
     { 
      return this.unitPrice; 
     } 

     set 
     { 
      this.unitPrice = value; 
      this.OnPropertyChanged("UnitPrice"); 
     } 
    } 

    public short? UnitsInStock 
    { 
     get 
     { 
      return this.unitsInStock; 
     } 

     set 
     { 
      this.unitsInStock = value; 
      this.OnPropertyChanged("UnitsInStock"); 
     } 
    } 

    public short? UnitsOnOrder 
    { 
     get 
     { 
      return this.unitsOnOrder; 
     } 

     set 
     { 
      this.unitsOnOrder = value; 
      this.OnPropertyChanged("UnitsOnOrder"); 
     } 
    } 

    public short? ReorderLevel 
    { 
     get 
     { 
      return this.reorderLevel; 
     } 

     set 
     { 
      this.reorderLevel = value; 
      this.OnPropertyChanged("ReorderLevel"); 
     } 
    } 

    public bool Discontinued 
    { 
     get 
     { 
      return this.discontinued; 
     } 

     set 
     { 
      this.discontinued = value; 
      this.OnPropertyChanged("Discontinued"); 
     } 
    } 

    public static Product CreateProduct(int productID, string productName, bool discontinued) 
    { 
     return new Product 
     { 
      ProductID = productID, 
      ProductName = productName, 
      Discontinued = discontinued, 
     }; 
    } 

    protected virtual void OnPropertyChanged(string changedProperty) 
    { 
     var propertyChanged = this.PropertyChanged; 
     if (propertyChanged != null) 
     { 
      propertyChanged(this, new PropertyChangedEventArgs(changedProperty)); 
     } 
    } 
} 

}

そしてNorthwindContextクラス:

public class NorthwindContext : DataServiceContext 
{ 
    public NorthwindContext(Uri serviceRoot) 
     : base(serviceRoot) 
    { 
     this.MergeOption = MergeOption.OverwriteChanges; 
     this.SaveChangesDefaultOptions = SaveChangesOptions.ContinueOnError; 
    } 

    public void AddToCategories(Category category) 
    { 
     this.AddObject("Categories", category); 
    } 

    public void AddToProducts(Product product) 
    { 
     this.AddObject("Products", product); 
    } 

    public void AddToSuppliers(Supplier supplier) 
    { 
     this.AddObject("Suppliers", supplier); 
    } 

    public void AttachToCategories(Category category) 
    { 
     this.AttachTo("Categories", category); 
    } 

    public void AttachToProducts(Product product) 
    { 
     this.AttachTo("Products", product); 
    } 

    public void AttachToSuppliers(Supplier supplier) 
    { 
     this.AttachTo("Suppliers", supplier); 
    } 
} 

}

、ここProductsPageViewModelクラスです:

public class ProductsPageViewModel : ListViewModel<Product> 
{ 
    public ProductsPageViewModel() 
     : this(Deployment.Current.Dispatcher, App.CloudClientFactory.ResolveNorthwindContext()) 
    { 
    } 

    public ProductsPageViewModel(Dispatcher dispatcher, NorthwindContext northwindContext) 
     : base(dispatcher, northwindContext) 
    { 
    } 

    protected override string EntitySetName 
    { 
     get 
     { 
      return "Products"; 
     } 
    } 
} 

}

答えて

0

EFを使用して作業している場合、データベースへの直接クエリはありません。 Domain Driven Designとは何かを読んでいました。 Persistent Ignoranceという戦略があります。これは、システムを設計しているときにデータストレージをまったく考慮する必要がないことを意味します。モデルのみで作業します。データマッパーパターンは、データベースに関連するすべてのことを行う場所を記述します。 Hereはいい記事ですが、私はあなたを助けることができると思います。
もう1つのアドバイスは、MVCが安らかなスタイルのWeb開発をサポートしていることを忘れないでください。これらの機能を活用することは、設計に役立ちます。

0

paramosh、

は、だから、初心者にそれを説明したりしないようにできますか?私はちょうどそのウェブサイトに行き、そのページを読んでいましたが、EFネットワークを傾けようとするのは本当に助けになりませんでした。

関連する問題